CMS(Consurrent Mark Sweep)并发标记清除。
CMS清理垃圾 主要分为4个节点,初始标记->并发标记 ->重新标记->清理,初始标记和重新标记时都会有STW(Stop The World)出现,即当前只有GC线程可以获取CPU执行权限,用户线程被挂起。
初始标记:
从GC Roots出发,找到能直接关联的对象,停顿时间很短,但仍需STW;
并发标记:
重点部分,GC Roots继续遍历对象图,此时用户线程也可以继续工作,但这样就会衍生出问题,初始标记时A a=new A(),但是在并发阶段a=null,这样导致GC看到的对象关系图谱已过时,这就是为什么需要接下来的Remark;
重新标记:
目的就是修改并发标记时,用户线程持续修改 对象图谱导致的对象关系图过时的问题,Remark仍然会STW重新确定标记,有出入就更新最新的对象关系;
并发清除:
标记过的对象记为存活,其他则是该被清理的对象。
CMS的优点:
1. 停顿时间短,它的设计之初就不是为了大吞吐量,而是减少用户线程的暂停时间,若重视大吞吐量则考虑 Parallel GC;
2. 大部分GC可以和用户线程并发执行。
缺点:
1. 内存碎片:标记存活对象,清理未被标记的死亡对象会造成内存不连续,即使总的空余内存足够创建新的对象,但没有一块连续的、足够大到的内存 仍然不能创建对象;
2. 浮动垃圾:这是并发标记导致的,并发标记确定a是存活对象,但是在清理期间又将a置为了null,从而出现GC之后仍然有死亡对象未被清理,需要在后续GC时回收;
3. Concurrent Mode Failure:
单个GC线程:垃圾未被清除前,用户线程还在持续创建新对象,空闲内存不足以满足新对象的内存分配;
多个GC线程:GC线程A正在执行CMS垃圾清理,GC线程B还在并发标记,同时用户线程还在持续创建对象,清理出来的内存 + 空余内存 不满足用户线程创建对象的需求;
本质是创建对象/对象晋升的速度 > CMS清理的速度。
CPU资源争夺:
4. 用户线程和GC线程争夺CPU执行权限,导致业务处理能力下降。