监控老年代需结合JVM参数、GC日志、jstat和可视化工具,重点关注内存趋势、GC类型触发条件及回收效果;开启-Xlog:gc*等日志,解析ParOldGen占用、GC原因、耗时;用jstat查OU/OC使用率;按G1/CMS/Parallel Old算法差异细化监控;结合MAT分析堆转储定位内存泄漏对象。

监控老年代空间占用与回收策略,核心是结合 JVM 参数、日志分析和可视化工具,重点关注老年代的内存变化趋势、GC 类型(如 CMS、G1、ZGC)触发条件及回收效果。
开启详细 GC 日志并解析关键指标
启动 JVM 时添加参数获取老年代相关日志:
- -Xlog:gc*,gc+heap=debug,gc+age=trace:file=gc.log:time,tags,level(JDK 10+,推荐)
- 或传统方式:-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
日志中重点关注:
-
老年代使用量:如
[PSYoungGen: ...] [ParOldGen: 123456K->78901K(262144K)]中ParOldGen后的数字(当前占用→回收后→总容量) - GC 类型:Full GC、Allocation Failure、Ergonomics、Metadata GC Threshold 等提示触发原因
- 耗时与吞吐:每次老年代 GC 的 pause time、是否伴随 Young GC、是否发生 promotion failure
用 jstat 实时观察老年代动态
运行中快速查看老年代容量与使用率:
立即学习“Java免费学习笔记(深入)”;
-
jstat -gc
1s :每秒刷新一次,关注OU(Old Used)、OC(Old Capacity)、OGCMN/OGCMX(老年代最小/最大容量) - 计算使用率:
OU / OC * 100%,持续高于 70% 可能预示频繁 Old GC 或内存泄漏 - 若
OU持续增长且不下降,说明对象未被回收,需配合堆转储进一步排查
按 GC 算法匹配监控重点
不同回收器对老年代管理逻辑差异大,监控侧重点不同:
-
G1:关注
mixed GC是否及时清理老年代分区;监控old generation occupancy是否接近InitiatingOccupancyPercent(默认 45%);用jstat -gc <pid></pid>查看MU(Metaspace Used)和CCSU(Compressed Class Space Used)是否间接影响老年代压力 -
Parallel Old:老年代 GC 即 Full GC,关注频率与单次耗时;若频繁发生,检查是否 Young GC 后晋升过多(
YGC次数多 +OGC增长快) -
CMS:监控
concurrent mode failure日志,说明并发收集失败退化为 Serial Old;关注initiating occupancy和promotion rate是否失衡
结合堆转储与 MAT 定位长期存活对象
当老年代持续增长或 GC 后仍高水位,需分析对象构成:
- 触发堆转储:jmap -dump:format=b,file=heap.hprof
(慎用于生产环境,建议配合 -XX:+HeapDumpBeforeFullGC) - 用 Eclipse MAT 打开,查看 Leak Suspects 报告,重点关注
java.lang.Class、静态集合、缓存容器(如ConcurrentHashMap、static List)引用的实例 - 按 Retained Heap 排序,识别占据老年代空间最多的对象及其 GC Roots 路径


















