Serial
新生代同步垃圾回收器,采用复制算法
单线程回收,对于小内存和单核CPU,性能优秀,但是当内存过大会回收时间会变长而使程序出现长时间卡顿
SerialOld
老年代垃圾回收器,采用标记整理算法,回收流程与Serial一样
Parallel Scavenge
新生代垃圾回收器,采用复制算法,可以通过设置停顿时间控制系统吞吐量。但需要注意的是,停顿时间减少意味着次数增加,需要权衡
多线程回收,效率很大提升,据说内存大于10G也不会出现系统卡顿
ParOld
SerialOld的多线程版本,回收流程和Parallel Scavenge一样
ParNew
同 Parallel Scavenge,只是为了和CMS配合使用
CMS
老年代垃圾回收器,采用标记清除算法
知识点
- 三色标记:未标记的对象标记为白色;自己标记完了,但是成员变量没有标记完为灰色;自己和成员变量都被标记完的为黑色
垃圾回收过程
- 初始标记:寻找GCRoot;
- 并发标记:从Root出发进行标记,根据三色标记的规则给对象标记颜色。该过程中如果对象的引用关系发生变更,使用写屏障获取变更信息,并将引用对象的颜色标记为灰色
- 重新标记:扫描灰色对象重新进行标记
- 并发清除:回收没有被引用的对象
注意:CMS用于生产需注意,标记清除算法会产生大量碎片空间。当空闲内存不足时启用SeriaOld垃圾回收器进行同步标记整理
G1
将对内存划分为若干Region,每个Region默认16M。Region分Eden,Survivor,Old和Humongous四个类型。其中Humongous为大对象区域,可能包含多个Region。垃圾回收时,并不一定会回收所有垃圾对象,视情况一次处理回收效率较高的一部分区域。
知识点
- 卡表:RemeberSet的具体实现。在进行YongGC的时候,需要了解老年代对年轻代的引用情况就需要扫描整个老年代,这个很耗费系统性能。JVM使用写屏障获取获取老年代对象对年轻代对象的引用变更,将对应的结果记录在卡表中,这样就不用扫描Region就可以知道对象引用情况,YongGC的时候就不用扫描整个老年代了。说明:写屏障为obj=null或者obj=new Object()
- 快照:初始标记完成以后,会给指针的引用生成一个快照,如果有被引用,就在一个栈空间放进指针信息进行标记。在重复标记的过程中,只扫描快照信息
G1垃圾回收过程解释
- Initial Mark(STW),通常和YoungGC一起发生,标记GCRoot,也可能是老年代对年轻代的引用
- Root Region Scanning,从GCRoot开始扫描直接引用的对象
- Concurrent Marking,找到整个堆的存活对象
- Remark(STW),完成堆中存活对象的最终确认,解决并发标记过程中堆中对象的变化,使用初始快照技术
- Cleaup,清除死亡对象
* 登记存活对象,并清空已空的区域(STW)
* 更新RememberSet(STW)
* 重置已经空闲的区域并注册到空闲列表中(Concurrent)
6.Copying(STW),复制过程,将多个空闲区域较大的Region合并为一个。如果GC过程被标记为Young,则只处理Young区;如果标记为mixed,则还会处理Old区