Java 9+必须用-Xlog:gc*:file=gc.log:time,uptime,level,tags开启GC日志,重点看Allocation Failure等标签定位原因;聚焦Young GC频率、Full GC效果、停顿时间、晋升速率四大指标,结合GCEasy分析并人工验证,OOM时联动堆快照用MAT定位泄漏根因。

直接看GC日志,不靠猜。面试官想听的是你有没有亲手分析过真实日志、能不能从日志里读出问题本质,而不是背概念。
怎么开启和解读GC日志
Java 9+统一用 -Xlog 参数,比如:
- -Xlog:gc*:file=gc.log:time,uptime,level,tags —— 输出带时间戳、运行时长、级别和标签的完整日志
- 关键要加 tags,这样能看到 GC 原因(如 Allocation Failure、Humongous Allocation),这是定位问题的起点
- 旧版参数如
-XX:+PrintGCDetails已过时,提它容易暴露知识未更新
看日志重点盯哪几项
不是通读,而是聚焦四个核心指标:
- Young GC 频率:每秒好几次?说明新生代太小,对象还没来得及死就反复回收
- Full GC 次数与效果:频繁发生且老年代回收后占用不降反升?大概率是内存泄漏
- 单次停顿时间:超过200ms就要警惕,尤其在低延迟场景下
- 晋升速率:每次 Young GC 都有大量对象进入老年代?可能是 Survivor 区太小或对象“熬”得太快
工具怎么用才显真功夫
光说“我用过 GCViewer”没用,得讲清楚怎么用:
- 把 gc.log 丢进 GCEasy,它会自动标出 “高频率 Minor GC”“可疑 Full GC”“内存泄漏倾向”等结论
- 但不能只信工具——比如 GCEasy 提示 “Allocation Failure 高频”,你要能接上:“这说明 Eden 区撑不住业务瞬时对象创建压力,下一步我会结合对象大小分布和线程堆栈,确认是不是某段代码批量 new 了大数组”
- 真正加分的是:你用日志定位过具体问题,比如发现 Humongous Allocation 导致 G1 频繁退化为 Full GC,然后调大
-XX:G1HeapRegionSize
遇到 OOM 怎么串联日志和堆快照
GC 日志是线索,堆快照才是证据:
- 先看日志里最后一次 Full GC 是否伴随 “Metaspace OOM” 或 “Java heap space”,区分是元空间还是堆溢出
- 堆溢出且 Full GC 后老年代持续上涨?立即用
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path获取 dump - 用 MAT 打开,看 Dominator Tree,找“谁持有了最多对象”——比如一个静态 Map 不断 put 却不清理,就是典型泄漏点











