请说明Java中触发Full GC的常见场景与条件。
考察说明
考查对JVM垃圾回收机制,尤其是Full GC触发条件的理解。
回答思路
- 【回答框架 1】触发Full GC的主要场景包括:老年代空间不足、元空间(Metaspace)空间不足、CMS并发模式失败或晋升失败(针对CMS收集器)、调用System.gc()但未禁用显式GC、以及大对象直接进入老年代导致空间不足等。
- 【回答框架 2】以CMS为例,当老年代使用率达到设定阈值(默认92%)时,会触发并发标记清理,若并发清理期间空间仍不足或发生并发模式失败,则退化为Serial Old收集器进行Full GC。G1收集器则在老年代占用超过阈值或Humongous对象分配失败时触发。
- 【回答框架 3】对象晋升失败也是常见诱因:年轻代Minor GC后存活对象无法放入老年代,且老年代空间不足或碎片化严重,会直接触发Full GC。此外,元空间用于存放类元数据,当加载类过多且空间不足时也会引发Full GC。
- 【回答框架 4】显式调用System.gc()会建议JVM执行Full GC,但实际是否执行及停顿时间受-XX:+DisableExplicitGC等参数影响。频繁Full GC往往伴随大量内存分配压力、配置不当或内存泄漏,需通过堆转储与GC日志定位根因。
- 【关键点 1】老年代空间不足是Full GC最常见的触发条件,包括对象晋升失败和大对象直接分配。
- 【关键点 2】元空间(Metaspace)空间不足也会触发Full GC,与类加载数量相关。
- 【关键点 3】CMS下并发模式失败或晋升失败会导致Full GC的Serial Old退化;G1则因老年代占用或Humongous对象分配失败触发。
- 【关键点 4】System.gc()显式触发需依赖参数设置,且会带来明显停顿。
- 【关键点 5】频繁Full GC需结合堆配置、GC日志和内存泄漏分析解决。
- 【易错点 1】将Full GC误解为仅由老年代空间不足导致,忽视元空间和显式GC等场景。
- 【易错点 2】未区分收集器差异,把CMS特有行为当作通用结论。
- 【易错点 3】忽略碎片化对晋升失败的影响,把原因简单归结为空间不足。