Java虚拟机面试题, 什么情况下会触发 Java 的 Full GC?
Java虚拟机面试题, 什么情况下会触发 Java 的 Full GC?
QA
Step 1
Q:: 什么情况下会触发 Java 的 Full GC?
A:: Java 的 Full GC 会在以下几种情况下触发:
1.
老年代空间不足:当老年代无法容纳新对象或老年代空间达到一定阈值时,会触发 Full GC。
2. 永久代(在 Java 8 之前)或元空间(在 Java 8
及之后)空间不足:当这些区域中的类加载元数据或常量池数据无法再存储新的数据时,会触发 Full GC。
3. 显式调用 System.gc()
方法:调用此方法建议 JVM 执行 Full GC(尽管不保证一定会执行)。
4.
老年代晋升失败:当新生代对象经过多次 Minor GC 后无法晋升到老年代,因为老年代空间不足时,会触发 Full GC。
5.
CMS GC 的并发模式失败:当 CMS 垃圾收集器在并发收集时发现老年代空间不足以容纳新对象时,会触发 Full GC。
Step 2
Q:: Full GC 和 Minor GC 有什么区别?
A:: Full GC 是针对整个堆内存(包括新生代、老年代和永久代/
元空间)的垃圾收集,而 Minor GC 仅针对新生代。Full GC 会暂停所有应用线程,因此代价更高,且通常比 Minor GC 频繁少。Minor GC 主要回收短命对象,而 Full GC 处理整个堆空间的对象,回收内存更多。
Step 3
Q:: 如何减少 Full GC 的频率?
A:: 减少 Full GC 的频率可以通过以下方法实现:
1.
调整 JVM 参数,增大老年代和新生代的大小,减少老年代的内存压力。
2.
优化代码,减少对象创建和提高对象存活率。
3. 避免频繁调用 System.gc()
。
4. 选择合适的垃圾收集器,例如 G1
、ZGC,这些收集器在处理老年代时更高效。
5. 调整 CMS 或 G1
垃圾收集器的参数,以避免并发模式失败或达到堆空间阈值时触发 Full GC。
Step 4
Q:: 如何分析和调优 JVM 的 GC 行为?
A:: 可以通过以下步骤分析和调优 JVM 的 GC 行为:
1. 启用 GC 日志:使用 -XX:+PrintGCDetails 和 -Xloggc:filename.
log 等参数记录 GC 日志。
2.
分析 GC 日志:使用工具如 GCViewer 或 GCeasy 分析 GC 日志,查看 GC 频率、停顿时间等信息。
3.
调整堆内存大小:根据分析结果,调整新生代和老年代的大小以平衡 GC 开销。
4. 选择合适的 GC 算法:根据应用的需求选择如 G1
、CMS、ZGC 等适合的垃圾收集器。
5.
优化代码:通过减少对象分配频率、避免内存泄漏等方法减少 GC 频率。
Step 5
Q:: 什么是 Java 堆内存的结构?
A:: Java 堆内存分为新生代(Young Generation)和老年代(Old Generation),新生代又分为 Eden 区、Survivor 0 区和 Survivor 1 区。新生代用于存放新创建的对象,老年代用于存放长期存活的对象。在 GC 过程中,新生代发生 Minor GC,老年代可能发生 Full GC。Java 8 之前还有永久代用于存放类信息和常量池数据,Java 8
之后则由元空间取代。