java 虚拟机 GC 学习笔记二
java 虚拟机常见 GC:
CMS GC(Mostly Concurrent Mark and Sweep Garbage Collector)
-XX:+UseConcMarkSweepGC
其对年轻代采用并行 STW 方式的 mark-copy (标记-复制)算法,对老年代主要使用并发 mark-sweep (
标记-清除)算法。
CMS GC 的设计目标是避免在老年代垃圾收集时出现长时间的卡顿,主要通过两种手段来达成此目标:
1. 不对老年代进行整理,而是使用空闲列表(free-lists)来管理内存空间的回收。
2. 在 mark-and-sweep (标记-清除) 阶段的大部分工作和应用线程一起并发执行。
也就是说,在这些阶段并没有明显的应用线程暂停。但值得注意的是,它仍然和应用线程争抢 CPU 时。
默认情况下,CMS 使用的并发线程数等于 CPU 核心数的 1/4。
如果服务器是多核 CPU,并且主要调优目标是降低 GC 停顿导致的系统延迟,那么使用 CMS 是个很明智
的选择。进行老年代的并发回收时,可能会伴随着多次年轻代的 minor GC。
CMS GC 包含六个阶段,分别是:
Initial Mark(初始标记):这个阶段伴随着 STW 暂停。初始标记的目标是标记所有的根对象,包括根对象直接引用的对象,以及被年轻代中所有存活对象所引用的对象(老年代单独回收)。
Concurrent Mark(并发标记):在此阶段,CMS GC 遍历老年代,标记所有的存活对象,从前一阶段 “Initial Mark” 找到的根对象开始算起。 “并发标记”阶段,就是与应用程序同时运行,不用暂停的阶段。
Concurrent Preclean(并发预清理):此阶段同样是与应用线程并发执行的,不需要停止应用线程。 因为前一阶段【并发标记】与程序并发运行,可能有一些引用关系已经发生了改变。如果在并发标记过程中引用关系发生了变化,JVM 会通过“Card(卡片)”的方式将发生了改变的区域标记为“脏”区,这就是所谓的 卡片标记(Card Marking)。
Final Remark(最终标记):最终标记阶段是此次 GC 事件中的第二次(也是最后一次)STW 停顿。本阶段的目标是完成老年代中所有存活对象的标记。因为之前的预清理阶段是并发执行的,有可能 GC 线程跟不上应用程序的修改速度。所以需要一次 STW 暂停来处理各种复杂的情况。通常 CMS 会尝试在年轻代尽可能空的情况下执行 Final Remark 阶段,以免连续触发多次 STW 事件。
Concurrent Sweep(并发清除):此阶段与应用程序并发执行,不需要 STW 停顿。JVM 在此阶段删除不再使用的对象,并回收他们占用的内存空间。
Concurrent Reset(并发重置):此阶段与应用程序并发执行,重置 CMS 算法相关的内部数据,为下一次 GC 循环做准备。
版权声明: 本文为 InfoQ 作者【风翱】的原创文章。
原文链接:【http://xie.infoq.cn/article/342ff63bdfe0f4ea71a21b3a8】。文章转载请联系作者。
评论