核心是三件事:判对象回收、选回收器、调优效果。一要动手验证GC Root失效场景,如静态变量置null、循环引用断链、局部变量出栈;二要按堆大小和GC日志(如STW超500ms、to-space exhausted)匹配回收器。

直接练核心,不堆概念。重点就三块:怎么判对象该回收、怎么选回收器、怎么调出效果。
一、对象存活判定必须动手写代码验证
光背“GC Root有7类”没用,得自己构造场景看它怎么失效:
- 写个静态变量持有一个大对象,再把它置为null,观察是否真被回收(用jstat或VisualVM看老年代变化)
- 故意制造循环引用(如A持有B、B持有A),再断掉外部引用,用jmap -histo确认这两个对象是否进回收队列
- 在方法里new对象后立即置null,但不return、不传参,观察局部变量表生命周期——它出栈那一刻,对象就失去GC Root了
二、回收器选择要匹配真实场景
别只记“G1是默认”,得清楚每种回收器在哪种压力下会翻车:
- 小堆(
- 中大堆(6–32GB)+响应敏感 → 用G1,必须配-XX:MaxGCPauseMillis=200(不是越小越好,JVM会妥协)
- 超低延迟要求(如金融交易)→ JDK 21+用ZGC,但得关掉分代(-XX:-ZGenerational),否则亚毫秒停顿不稳
三、调优不是调参数,而是盯指标反推问题
真正有效的调优,从日志和监控倒着来:
立即学习“Java免费学习笔记(深入)”;
- 频繁Young GC → 不是调-Xmn,先看对象是不是短命却过大(比如一次读MB级JSON),考虑对象池或流式解析
- Old GC突然增多 → 用jstack查是否有线程长期持有缓存、监听器未注销、ThreadLocal未remove
- GC时间占比高(>10%)→ 开-XX:+PrintGCDetails,统计单次STW时长,若G1 Mixed GC超500ms,说明老年代碎片化严重,需加大-XX:G1HeapRegionSize
练到能看懂GC日志里的“to-space exhausted”“promotion failed”“concurrent mode failure”,就算入门了。


















