Java 虚拟机面试题, Java 中 CMS 垃圾收集器的写屏障如何维护卡表和增量更新?
Java 虚拟机面试题, Java 中 CMS 垃圾收集器的写屏障如何维护卡表和增量更新?
QA
Step 1
Q:: Java 中 CMS 垃圾收集器的写屏障如何维护卡表和增量更新?
A:: CMS(Concurrent Mark-Sweep)垃圾收集器是一种基于标记-
清除算法的收集器,它的主要目标是减少应用程序的停顿时间。CMS 使用写屏障来维护卡表和进行增量更新。写屏障是一种字节码指令或硬件指令,它在应用程序的每次对象引用修改时被触发。CMS 的写屏障用于维护一个卡表,该卡表是用于跟踪特定内存区域中的对象是否已被修改。卡表的每一项对应一个内存区域(卡),当该区域中的对象被修改时,写屏障会将对应的卡标记为脏卡(Dirty Card)。在 CMS 的增量更新阶段,垃圾收集器会扫描这些脏卡,重新标记其中的对象,以确保在垃圾收集时,这些对象能够被正确识别。
Step 2
Q:: CMS 垃圾收集器有哪些优点和缺点?
A:: 优点:1. CMS 最大的优点是并发收集和低停顿时间,非常适合对响应时间敏感的应用。2. CMS 在收集过程中不需要暂停应用程序的所有线程,允许应用程序和垃圾收集器并行运行。缺点:1. CMS 的垃圾收集会产生内存碎片,因为它是基于标记-清除算法,而不是标记-整理算法。2. CMS 在低内存情况下可能会出现'Concurrent Mode Failure',导致应用程序进入Full GC,这会带来更长的停顿时间。3.
CMS 相较于其他垃圾收集器,对 CPU 资源的需求较高。
Step 3
Q:: CMS 的增量更新和初始标记阶段有何区别?
A:: 初始标记阶段是 CMS 垃圾收集器的第一个阶段,这个阶段会标记所有从根集合(GC Roots)直接可达的对象。这个阶段需要短暂地暂停所有应用程序线程(Stop-The-
World),但时间通常较短。增量更新阶段则是 CMS 的并发阶段之一,在该阶段,垃圾收集器会跟踪在初始标记之后被修改的对象,以确保这些对象也能被正确标记为活跃对象。这是通过写屏障机制来实现的。
Step 4
Q:: 在 CMS 的垃圾收集过程中,什么时候会出现'Concurrent Mode Failure'
?
A:: 当 CMS 在并发清除阶段来不及回收内存,导致可用内存不足以满足应用程序分配需求时,会出现'Concurrent Mode Failure'
。这时,JVM 会被迫触发一次 Full GC 来解决内存不足的问题,Full GC 是一种完全暂停所有应用程序线程的垃圾收集过程,通常会带来较长的停顿时间。
Step 5
Q:: 如何避免 CMS 垃圾收集器的内存碎片问题?
A:: CMS 垃圾收集器的内存碎片问题可以通过以下几种方式缓解:1. 调整 CMS 的启动阈值和参数,例如通过增加堆内存大小或降低触发 Full GC 的阈值。2. 使用 CMS 的内存压缩功能(通过配置参数 -XX:+UseCMSCompactAtFullCollection),在 Full GC 之后对内存进行压缩整理。3. 在可能的情况下,切换到 G1
垃圾收集器,它结合了 CMS 的低停顿特性,并且通过区域化堆内存管理有效地减少了内存碎片。