欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java基础---虚拟机---CMS并发标记垃圾回收器

程序员文章站 2022-04-20 17:39:44
https://www.cnblogs.com/Leo_wl/p/5393300.html https://www.cnblogs.com/Leo_wl/p/5393300.html 简述CMS垃圾回收器垃圾回收的几个流程 CMS作用于老年代的垃圾回收,但是也会扫描新生代的内容 1.初始标记阶段。用 ......
https://www.cnblogs.com/Leo_wl/p/5393300.html
https://www.cnblogs.com/Leo_wl/p/5393300.html

====简述CMS垃圾回收器垃圾回收的几个流程
 
CMS作用于老年代的垃圾回收,但是也会扫描新生代的内容
 
1.初始标记阶段。用户线程暂停,标记所有和根对象直接相连的对象。
 
2.并发标记阶段。用户线程起来,这个阶段标记所有可到达的对象
 
3.预处理阶段。因为用户线程起来了,所以可能有修改对象或者新增的对象,这个阶段就是标记从新生代转移到老年代的对象,老年代新分配到的对象以及修改的对象等等。
因为下一个阶段是重标记,必须做GC停顿来扫描新生代和老年代,如何让这个停顿时间少,如何更快的扫描标记,就是本阶段的任务,所以预处理对新生代和老年代都做了相应的处理。
-----预处理阶段新生代的处理方式:1.进行minorGC        2.remark阶段会并发扫描新生代,所以预处理会将新生代分块,分快给多个线程处理。
-----预处理阶段老年代的处理方式:1.使用Card Table加速扫描,是一个字节数组。老年代分块,每一块关联card table中一个字节。1.如果在并发标记阶段对象被用户线程修改了,就会标记成dirty card,预处理阶段进行可达性标记,然后把dirty card标记清除,这样并发标记阶段修改的对象也会被标记;2.如果老年代引用到新生代,也可以通过cardTable快速扫描到。
 
4.重标记阶段。暂停用户线程,重新标记可到达对象。预处理后这个阶段速度会加快。
 
5.并发清理的阶段。用户线程同时进行执行,产生 
 
6.重置。准备下个阶段的垃圾回收。
 

===CMS会带来什么问题呢?
1.并发的问题
CMS默认使用的GC线程数量为(CPU+3)/4,如果cpu数量少的时候比如只有两个,就会有1个进行GC那么应用就会有百分50的性能下降会很明显,但是当cpu数量上升的时候就不会有这种问题了。
 
2.并发的第二个问题。gc线程用户线程同步执行,就会有浮动垃圾产生。同时需要给用户线程提供执行的空间,也就是说不能等到老年代满了才进行垃圾回收,默认是到达百分92进行老年代垃圾回收。当然这个参数是可以设置的。太小了会使得gc频繁就会有停顿,太大了可能会导致用户线程无法执行,因为需要的空间不够,这个时候会导致使用串行回收器进行回收,停顿时间会更长。
 
3.标记清楚法带来的问题:内存碎片,可能老年代剩余空间很大但是因为内存碎片的原因,没有很大的连续内存空间,大对象进来可能就会触发垃圾回收。CMS的解决方式是通过设置在进行几次回收之后进行内存压缩。
 

====如果要标记老年代的对象,需要扫描新生代吗?如何加快新生代的扫描呢?预处理的阶段如何控制呢?
 
要标记老年代的对象需要扫描新生代,要想加快新生代的扫描就要让新生代里面的对象变少,也就是进行一次垃圾回收。
预处理阶段因为用户线程也在跑,那么对象会一直变化,总得要有个停下来的时候,这个时候可以设置参数让它停下来。