# 协同Java服务JVM内存/线程巡检和调优手册

# 前言

本手册针对协同OA使用的Java Web服务核心组件 [JVM虚拟机] 进行巡检和调优指导,以便项目组能参照手册自主做检查。

JVM巡检的重要性:如果JVM的参数配置错误、不做常规巡检观察系统状态,可能会在服务器产生性能问题时无法及时分辨处置,故项目上都需要做好巡检和调优。

协同OA标准适配Java JDK8,故本手册基于JDK8版本的JVM调优做叙述。

建议花几个小时,通过网上视频学习一下JVM入门基础,对JVM运行原理有个基本理解,不用过于深入,能基本了解:栈、堆、元空间、新生代Eden区、新生代Survivor区、老年代Old Gen、垃圾回收器、-Xmx-XX:MetaspaceSize 等JVM参数配置即可。 学习之后,才能充分理解为什么需要JVM调优,应该怎么调优。在后面跟研发沟通 和 客户的技术沟通会更加游刃有余,更具专业性。

# 巡检步骤

# 1、检查垃圾回收器G1GC

第一步检查垃圾回收器: JVM提供了多种垃圾回收算法,由于V5产品是单体应用,高在线用户下服务器都是大内存,故标准产品要求使用G1GC这种垃圾回收算法(G1对大内存、低延迟、高吞吐量的场景具备均衡且优秀的表现)。

检查方法: OA系统管理员后台 → 系统监控菜单 → JVM表格找到最后一行(Gen列):

  • 如果是 G1 开头,则说明配置正确!
  • 如果是别的,如 PS 开头,则说明配置错误,需要修正!

1765356380571.png

非G1GC潜在风险: 一般如果不设置G1GC垃圾回收器,默认均是PS GC(Parallel Scavenge GC)垃圾回收算法,PS GC模式在大堆下,若业务产生大对象或长期存活对象过多,老年代会快速占满,触发频繁 Full GC—— 而每次 Full GC 都是长时停顿,形成恶性循环。 通俗说:用户在线越高、JVM堆内存越高,使用PS GC越容易出现系统全面卡顿一段时间,然后恢复正常,再过一会儿又出现全系统卡顿等问题。

G1GC垃圾回收特点: 对比PS GC垃圾回收器,G1 GC在面对高在线、高堆内存场景,回收会温和的多:G1GC 对老年代的回收不是等到内存满了才全量清理,而是通过 Mixed GC(混合回收) 实现增量式清理。 通俗说,就是使用一会儿就悄悄回收一部分不用的内存资源,这种温和的回收方式不会触发Full GC,自然不会导致系统卡顿。

不过,如果客户的在线用户高、堆内存配置过低 或者 存在内存泄漏代码,会导致G1GC不会增量式清理,而是等到内存涨到80%以上再强制Full GC,这种情况也会导致系统卡顿。 通俗说:G1GC肯定是“政治正确”的配置,但如果客户内存过低(又遇到高并发)、或者程序中存在内存滥用的代码还是会导致系统卡顿,这种就需要通过后续巡检步骤排查!

配置G1GC垃圾回收器方法: 如果确定不是使用G1GC,处理方法根据项目上不同产品线和中间件来判断调整:

  • 如果是A6、A8、G6非信创产品线,使用标准的安装程序(默认Tomcat中间件),产品肯定是G1GC,这种不存在调整的情况
  • 如果是A8N、G6N信创产品线,使用金蝶、东方通、宝兰德、中创、普元、华宇中间件,则可能遇到没有配置G1GC垃圾回收算法的情况!

信创环境下配置G1GC垃圾回收算法的通用处理办法:

  • 1)如果是V9.0及以上版本,则建议使用XinChuang信创部署工具部署产品,工具会自动向中间件配置G1GC以及若干重要的JVM参数,简言之:V9.0版本之后使用信创部署工具部署都不会存在没有设置G1GC的问题
  • 2)情况特殊,没有办法使用工具部署OA产品到信创中间件(专用机、非标中间件、低版本),则需要自行到对应中间件的管理控制台→JVM页签进行垃圾回收器配置,配置后需要重启中间件才能生效。不同中间件位置不同,可以参考最新版本信创部署手册对应中间件的JVM检查章节
  • 3)非标中间件(如中创、普元、华宇),可以咨询中间件厂商协助配置
  • 4)标准中间件但没有配置G1垃圾回收器选项(如金蝶V9)或者配置后无效的情况(如宝兰德特定版本),同样可以咨询中间件厂商协助配置

1765360484259.png

1765360659731.png

扩展说明: 关于为什么会存在垃圾回收,什么情况回收,回收链路,JVM怎么占用内存资源的问题,需要大家自学JVM原理了解基础。

# 2、检查JVM堆内存配置合理性

第二步检查JVM堆内存配置合理性: JVM 堆内存是OA应用运行时变量缓存存储的核心空间,高在线用户场景下会产生大量临时对象与常驻对象,故一定要根据客户在线用户数、内存使用率和服务器物理内存 动态调配JVM堆内存配置!简言之:JVM堆内存不是固定的,一定要根据项目使用情况个性化调整。

详细检查方法: OA系统管理员后台 → 系统监控菜单 → JVM表格找到最后一行:

  • 日常情况只需要 重点关注JVM表格最后一行(下图示例标记的几个参数是重要参数) ,别的行不用在意
  • 最后一行Init列:此值可以简单看出-Xms配置合理性。
    • 最后一行Init列对应老年代初始申请的内存,这个值需要跟最后一行Max列做对比,两者数值不要差别太大,如Init列1G,而Max列8G,则可能是 -Xms 最小堆未配置或配置过低。
    • 生产环境建议:-Xms最小堆内存和-Xmx最大堆内存配置一致或接近,以避免JVM运行时动态调整堆大小引发性能抖动。
    • -Xms8g -Xmx8g-Xms32g -Xmx48g都是推荐的配置形态。
    • 以上示例是以GB为单位,有的中间件以MB为单位,故需要乘以1024倍,比如 -Xms8192m -Xmx8192m 对应8G大小堆内存,注意换算。
  • 最后一行Max列:此值可以简单看出-Xmx的配置。
    • 这个值就是JVM堆内存可申请的最大值,程序只能用这么多堆内存。这个值需要根据Used Ratio和Peak Ratio动态调控。
  • 最后一行Used Ratio列:体现系统当前实时使用的老年代堆内存使用情况,计算公式是[Used÷Max]的百分比。
    • 以Used 1.34G、Max 8G、Used Ratio 17%为例,表示:JVM从物理内存申请了8G内存独占,但程序实际只消耗了1.34G内存,占申请比例的17%。
    • Used Ratio体现的时刷新页面那一时刻的数据,如果再刷新系统监控菜单,这个数值又会变化。
    • 一般Used Ratio在70%以下都是良好的!如果经常超过70%,并且长期不降低,或者突然一个全系统卡顿才降低,那就可能是Jvm Max堆内存申请不够。建议根据服务器物理剩余内存情况,扩大JVM的对内存配置。
    • 生产环境OA独占一台服务器资源场景下,一般推荐JVM的-Xmx最高可占用服务器总内存的75%(剩余物理内存需要给Java堆外内存、操作系统、杀毒软件使用)。
    • 首次部署环境,则参考对应部署手册服务器阶梯资源要求,申请资源的50%以上做堆内存。
    • 首次部署如500用户在线要求服务器物理内存32G以上,则JVM配置为-Xms16g -Xmx16g
    • 首次部署如1500用户在线要求服务器物理内存64G以上,则JVM配置为-Xms32g -Xmx32g-Xms32g -Xmx48g
  • 最后一行Peak Ratio列:体现系统运行以来,程序峰值占用内存情况,即程序最大使用了多少比例的内存。
    • 假设你平时没有时间关注Used Ratio列,那么Peak Ratio列就是非常重要的参考指标!可以在用户高频使用系统当天观察Peak Ratio的值来判断JVM是否要调整或者是否存在性能问题。
    • 通俗说,如果Peak Ratio列数值超过了80%,建议做JVM堆内存扩容或监控分析OA程序性能。
    • 比如200在线用户数,JVM配置-Xms8g -Xmx8g,Peak Ratio值为85%,服务器物理内存32G(OA独占),则建议JVM配置扩大为-Xms16g -Xmx16g,重启OA再次日观察效果。
    • 再比如500在线用户数,JVM配置已经达到-Xms48g -Xmx48g(远超推荐配置),Peak Ratio值为95%,Used Ratio值多次刷新总出现70% → 75% → 80%久增不降,并且还出现系统大面积卡顿,则要关注程序内存泄漏问题,这个排查方法在后面章节说明。
    • 简单总结:Peak Ratio列超过80%要关注,如果低于或持平推荐配置,则考虑扩大一定的JVM堆内存观察;如果JVM配置已经远高于推荐配置,还经常卡顿,则可能是程序性能问题。

1765362314940.png

修改JVM最大堆、最小堆内存方法: 非信创(Tomcat中间件)和信创(金蝶、宝兰德、东方通等中间件)修改方法不同:

  • 非信创Tomcat中间件在SeeyonConfig可视化面板下修改,新版本非信创部署手册中会有 [JVM调整章节 (opens new window)] 详细介绍修改方法。
  • 信创中间件,需要在各自中间件管理控制台JVM面板下修改,新版本信创部署手册每个中间件中都会有 [JVM堆内存调整 (opens new window)] 的说明。

1765422133776.png

# 3、检查HTTP最大线程配置

# 4、检查其它JVM重要配置

# JVM对物理内存的占用原理

常识:基于Java开发的程序离不开JVM内存管理,并且不接受操作系统动态调控。

编撰人:het