Java 虚拟机面试题, 为什么 Java 中 CMS 垃圾收集器在发生 Concurrent Mode Failure 时的 Full GC 是单线程的?
Java 虚拟机面试题, 为什么 Java 中 CMS 垃圾收集器在发生 Concurrent Mode Failure 时的 Full GC 是单线程的?
QA
Step 1
Q:: 为什么 Java 中 CMS 垃圾收集器在发生 Concurrent Mode Failure 时的 Full GC 是单线程的?
A:: Concurrent Mode Failure 是指在 CMS 收集器进行并发垃圾收集过程中,由于在重新标记阶段没有足够的内存来分配给新的对象,从而不得不中断 CMS 进程并触发一次 Full GC。在 CMS 中,Full GC 是单线程的,因为 CMS 的设计初衷是为了尽量减少垃圾收集对应用程序的暂停时间,但在 Concurrent Mode Failure 的情况下,系统必须优先保证内存可用性,此时会回退到 Serial Old 垃圾收集器,这个收集器是单线程的。这种机制虽然会带来更长的停顿时间,但在内存耗尽的情况下是必须的。
Step 2
Q:: CMS 垃圾收集器的优缺点是什么?
A:: CMS 垃圾收集器的主要优点是低停顿时间,适合那些需要快速响应的应用程序(如交互式应用)。它的缺点是会产生内存碎片,且在内存紧张时,可能会频繁触发 Full GC。同时,CMS 使用更多的 CPU 资源,因为它与应用线程并发运行。
Step 3
Q:: 什么是内存碎片?为什么 CMS 垃圾收集器会产生内存碎片?
A:: 内存碎片是指内存中的可用空间被分散为多个不连续的块,无法满足较大对象的分配需求。CMS 垃圾收集器采用标记-清除算法,这种算法只清理垃圾对象而不进行内存压缩,导致存活对象之间的空闲区域可能非常零碎,最终可能导致 'Concurrent Mode Failure'
。
Step 4
Q:: 如何解决 CMS 垃圾收集器中的内存碎片问题?
A:: 可以通过以下几种方式来解决 CMS 垃圾收集器的内存碎片问题:1) 调整 JVM 参数,如增加堆内存或使用适当的垃圾收集器组合;2) 在 CMS 中手动触发 Full GC 来进行内存压缩;3) 使用 G1
垃圾收集器,它可以有效地减少内存碎片,同时提供可预测的停顿时间。
Step 5
Q:: 什么是 CMS 垃圾收集器中的 'Initial Mark' 和 'Remark'
阶段?
A:: CMS 垃圾收集器的 'Initial Mark' 阶段用于标记所有 GC Roots 直接引用的对象,这是一个短暂停顿阶段。'Remark'
阶段用于标记在并发标记阶段未被标记到的对象,这也是一个暂停阶段,但时间较短。这两个阶段都是 STW(Stop The World)操作。