在JVM Hotspot中,我们知道JVM需要在某些标记短语期间停止mutator线程(STW),例如在GC类型CMS和G1标记根时的年轻代和旧代初始标记短语。
我是否知道为什么在这些短语中必须使用STW?为了避免mutator和mark thread之间的竞争条件?
我们是否可以使用与并发标记短语相同的技术来避免使用STW?
答案 0 :(得分:1)
当CMS收集器需要运行时,需要标记根集。这是可从当前堆栈帧加上静态引用直接访问的对象集。如果在发生这种情况时允许mutator线程运行,则可能会错过引用,因为会弹出堆栈帧并推送新帧。
在标记了根集之后,GC有一个准确的起点,可以从该应用程序代码中跟踪所有其他可引用的对象。这部分可以与mutator线程同时发生。
一旦跟踪了可达对象的完整图形(同时),就需要第二个STW重新标记阶段,以便在并发标记阶段进行过程中所做的更改可以集成到有效对象引用列表中。
此时,可以使用并发扫描阶段(因为现在已知所有有效对象)来更新有效对象之间可用内存区域的空闲列表。除非碎片变得太大或自由空间变得太小,否则不会进行压缩,此时会启动完整的压缩集合。