1 CMS收集器
CMS收集器是以获取最短回收停顿时间为目标的老年代收集器, 所以非常适合希望停顿最短时间及要求响应速度的程序,能给用户带来更好的体验。
1.1 CMS收集器的过程
初始标记(STW): 只标记与GC ROOT关联的对象, 速度快。
并发标记: 对初始标记标记出来的对象进行继续搜索, 标记出与之关联的对象
重新标记(STW): 修正并发标记期间因用户程序继续运行而导致标记变动的那一部分标记记录, 时间比初始标记稍长
并发清理: 并发的清理回收垃圾对象
1.2 CMS优点
并发收集、低停顿。 CMS收集器整个收集的过程中耗时最长的并发标记和并发清理都能与用户线程并发执行, 所以应用程序停顿短, 自然而然响应速度也随之提升
1.3 CMS缺点
CPU敏感: 并发阶段会占用部分CPU(线程)资源,导致应用程序响应变慢,吞吐量降低。
无法处理浮动垃圾: 由于并发清理阶段用户线程继续运行, 在运行的过程会产生新的垃圾, 这部分垃圾在当次收集无法被处理掉,只能等下次GC时回收, 这部分垃圾称为浮动垃圾。如果CMS运行期间预留的内存无法满足程序的需要, 就会发生Concurrent Mode Failure失败, 此时JVM将会临时启用Serial Old进行回收, 由于Serial Old是单线程的, 那停顿的时间将会更长
产生内存碎片: CMS采用的使用标记—清除算法, 这个算法的缺点会导致大量内存碎片, 往往导致老年代还有大量的内存空间而无法申请连续的内存空间导致FullGC。
2 G1收集器
2.1 G1的优势
并发与并行: G1是一款面向服务端的垃圾收集器, 能充分利用多CPU、多核环境下的硬件优势, 缩短STW停顿时间,部分其他收集器需要停顿Java线程执行的GC动作,G1能做到并发执行。
分代收集: G1也有分代的概念, 同时无需与其他垃圾收集器配合; G1之前会将堆内存划分为年轻代和老年代(物理隔离), 而G1是将堆内存划分为多个大小相等的区域(Region),但保留了新生代和老年代的概念(不是物理隔离)。
空间整合: G1采用标记—整理算法, 不会造成内存空间碎片。 从局部看使用的是复制算法(两个Region之间)。
可预测的停顿: G1和CMS的目标都是降低停顿时间, 但G1除了追求停顿时间之外, 还能建立可预测的停顿时间模型,能让使用者明确在规定的时间段内, 消耗在垃圾收集上的时间不得超过指定时间。G1会根据各个Region里垃圾堆积的价值大小维护一个优先列表, 每次根据允许的收集时间, 优先收集价值最大的Region,以保证在有限的时间内尽可能提高收集的效率。
2.2 G1垃圾收集过程
初始标记(STW): 标记与GC ROOT关联的对象, 并且修改TAMS的值,使并发标记阶段用户线程并发运行时可以找到可用的Region创建对象, 该阶段耗时很短。
并发标记: 从GC ROOT开始对堆中的对象进行可达性分析, 找出存活对象, 耗时较长, 但可与用户线程并发执行。
最终标记(STW): 修正在并发标记期间因用户线程运行而导致标记改变的那一部分标记记录, 虚拟机会将这段时间对象变动的记录在线程log里, 最终标记阶段只需将log中的数据合并即可, 该阶段停顿用户线程, 但可并行执行。
筛选回收: 对各个Region的回收价值和成本进行排序, 根据用户所期望的GC停顿时间制定回收计划,该阶段可以和用户线程并发执行。