赞
踩
作者:刘宇
CSDN博客地址:https://blog.csdn.net/liuyu973971883
有部分资料参考,如有侵权,请联系删除。如有不正确的地方,烦请指正,谢谢。
CMS(Concurrent Mark Sweep)收集器,以获取最短回收停顿时间为目标,多数应用与互联网或者B/S系统的服务器端上。
CMS是基于“标记-清除”,算法实现的,整个过程分为4个步骤:
初始标记(CMS initial mark):
需要Stop The world,只是标记一下GC Roots能直接关联到的对象,速度很快。
并发标记(CMS concurrent mark):
它是GC Roots Tracing的过程
重新标记(CMS remark):
需要Stop The world,是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿实际一般会比初始标记阶段稍微长一些,但远比并发标记的时间短。
并发清除(CMS concurrent sweep)
CMS收集器的运作步骤如下图所示,在整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,因此,从总体上看,CMS收集器的内存回收过程是与用户线程一起并发执行的。
并发收集、底停顿,Oracle公司的一些官方文档中也称之为并发底停顿收集器(Concurrent Low Pause Collector)
在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。当大量对象在Minor GC后仍然存活,就需要老年代进行空间分配担保,把Survivor无法容纳的对象直接进入老年代。如果老年代判断到剩余空间不足(根据以往每一次回收晋升到老年代对象容量的平均值作为经验值),则进行一次Full GC。
这个是CMS两次Stop The World事件的其中一次,这个阶段的目标是:标记哪些直接被GC Root引用或者被年轻代存活对象引用的所有对象
在这个阶段Garbage Collector(垃圾收集器)会遍历老年代,然后标记所有存活的对象,它会根据上一个阶段找到的GC Roots遍历查找。并发标记阶段,它会与用户的应用程序并发运行。并不是老年代所有的存活对象都会被标记,因为在标记期间用户的程序可能会改变一些引用。
在上面的图中,与阶段1的图进行对比,你就会发现有一个对象的引用已经发生了变化。
这也是一个并发阶段,与应用的线程并发运行,并不会stop应用的线程。在并发运行的过程中,一些对象的引用可能会发生变化,但是这种情况发生时,JVM会将包含这个对象的区域(Card)标记为Dirty,这也就是Card Marking
在pre-clean阶段,那些能够从Dirty对象到达的对象也会被标记,这个标记做完之后,dirty card标记就会被清除了。
在 preclean 执行后,dirty card 被清理,被修改的引用信息也被更新。
这也是一个并发阶段,但是同样不会影响用户的应用线程,这个阶段是为了尽量承担STW(stop-the-world)中最终标记阶段的工作。这个阶段持续时间依赖于很多因素,由于这个阶段是在重复做很多相同的工作,直接满足一些条件(比如:重复迭代的次数、完成的工作量或者时钟时间等)
这里不需要STW,它是与用户的应用程序并发运行,这个阶段是:清除那些不再使用的对象,回收它们的占用空间为将来使用
这里找了很多文章也没有找到是如何保证的,只有一篇关于三色标记的文章似乎能说得通文章1、还有这篇讲解了三色标记、浮动垃圾、读写屏障等文章2
网上有很多答案,有的说CMS在清理的时候要预留一定的空间供用户线程使用,用于存储新生代晋升过来的新对象,保证了在并发清除的时候新对象不会被清除;还有一种在上面的文章1中有介绍到。
这个阶段也是并发执行的,它会重设CMS内部的数据结构,为下次GC做准备
JVM运行参数:
-verbose:gc
-Xmx20m
-Xms20m
-Xmn10m
-XX:+PrintGCDetails
-XX:SurvivorRatio=8
-XX:+UseConcMarkSweepGC
代码:
package com.brycen.demo.gc;
public class MyTest5 {
public static void main(String[] args) {
int size = 1024*1024;
byte[] myAlloc1 = new byte[4*size];
System.out.println("11111");
byte[] myAlloc2 = new byte[4*size];
System.out.println("22222");
byte[] myAlloc3 = new byte[4*size];
System.out.println("33333");
byte[] myAlloc4 = new byte[2*size];
System.out.println("44444");
}
}
运行结果:
11111
[GC (Allocation Failure) [ParNew: 6621K->701K(9216K), 0.0040330 secs] 6621K->4799K(19456K), 0.0040867 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
22222
[GC (Allocation Failure) [ParNew: 4954K->109K(9216K), 0.0052423 secs] 9052K->8845K(19456K), 0.0052754 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
[GC (CMS Initial Mark) [1 CMS-initial-mark: 8736K(10240K)] 12941K(19456K), 0.0002225 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-mark-start]
33333
44444
[CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-abortable-preclean-start]
[CMS-concurrent-abortable-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (CMS Final Remark) [YG occupancy: 6575 K (9216 K)][Rescan (parallel) , 0.0057096 secs][weak refs processing, 0.0000137 secs][class unloading, 0.0003602 secs][scrub symbol table, 0.0007289 secs][scrub string table, 0.0002154 secs][1 CMS-remark: 8736K(10240K)] 15311K(19456K), 0.0071343 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
par new generation total 9216K, used 6739K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
eden space 8192K, 80% used [0x00000007bec00000, 0x00000007bf279818, 0x00000007bf400000)
from space 1024K, 10% used [0x00000007bf400000, 0x00000007bf41b4b0, 0x00000007bf500000)
to space 1024K, 0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)
concurrent mark-sweep generation total 10240K, used 8735K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
Metaspace used 3200K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 355K, capacity 388K, committed 512K, reserved 1048576K
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。