3.5经典垃圾收集器
并行:描述的时垃圾收集线程之间的关系,标识多条垃圾回收线程再协同工作,此时默认用户线程时处于等待状态的。
并发:描述的是垃圾回收线程和用户线程的关系,说明同一时间垃圾收集线程和用户线程同时工作。
1、Serial收集器
特点:
*历史最悠久的垃圾收集器
*进行垃圾回收时会暂停所有工作线程(stop the world),直到垃圾回收结束
*采用 标记-复制算法
(serial/serial old 收集器运行示意图)
优点:对于内存资源受限制的环境,serial收集器是所有收集器里额外内存消耗最小的(因为没有了线程交互的开销),所以对用应用在客户端模式下的虚拟机是一个很好的选择。
缺点:Stop The World 会给用户带来恶劣的体验
2、ParNew收集器
特点:
*Serial收集器的多线程并行版本,除了同时使用多条线程进行垃圾收集外,其余行为包括Serial收集器的可用参数、收集算法、stop the world 、对象分配规则、回收策略等都与serial完全一致。
(ParNew/serial old 收集器运行示意图)
3、Parallel Scavenge收集器
特点:
*是一款新生代收集器,采用 标记-复制算法
*能够并行收集的多线程收集器
*目标是 达到一个可控制的吞吐量 (吞吐量 = 运行用户代码时间/(运行用户代码时间+运行垃圾收集时间))
参数:
-XX:MaxGCPasueMillis 设置最大暂停时间
-XX:GCTimeRatio 设置目标吞吐量大小
4、Serial Old 收集器
特点:
* Serial收集器的老年版本
*一款单线程收集器
*采用 标记-整理算法
(serial/serial old 收集器运行示意图)
5、Parallel Old收集器
特点:
*Parallel Scavenge 的老年代版本
*支持多线程并行收集
*采用 标记-整理算法
(Parallel Scavenge/Parallel Old收集器运行示意图)
CMS收集器(Concurrent Mark Sweep)
** ** 特点:
*以获取最短暂停时间为目标的收集器
*采用 标记-清除算法
步骤:
-初始标记(stop the world)
标记一些直接与 GC root 关联的对象(耗费时间较短)
-并发标记
从GC root直接关联的对象开始进一步遍历对象图的过程(耗费时间长,但可以并发执行)
-重新标记(stop the world)
为了修正并发标记期间,由于用户程序继续运作而导致标记产生变动的那一部分标记记录
-并发清除
清除掉标记阶段被标记为已死亡的对象
优点:并发收集、低停顿
缺点:①CMS对处理器资源非常敏感,再并发阶段,它虽然不会导致用户线程停顿,但是会因为占用了一部分线程(处理器的计算能力)所以会导致应用程序变慢,降低总吞吐量。
②CMS无法处理浮动垃圾,有可能出现“concurrent Mode Failure”失败进而导致另一次完全的 Full GC 产生(Serial Old)。(浮动垃圾:再CMS的并发标记、并发清除阶段用户线程是还在继续运行的,也就是说此时自然会有新的垃圾产生,但是这些垃圾对象时出现再标记过程之后,所以导致本次GC无法处理,只能留待下一次GC处理,这种垃圾就成为浮动垃圾)
③标记清除算法会导致产生大量碎片化空间
Garbage First 收集器(G1GC)
** ** 特点:
*G1可以针对堆内存任意部分来组成回收集合,衡量标准不再是它属于那个分代,而是那块区域中存在的垃圾最多回收的收益最大(Mixed GC 模式)
*虽然G1仍是遵循分代收集理论设计的,但是G1不在坚持固定大小固定数量的分代区域划分,而是将堆划分为多个大小相等的独立区域(Region),每个Region都可以根据需要去扮演,新生代的Eden、Survivor空间或者老年代空间。Region还有一类特殊的区域Humongous用于存放大对象(大小超过了Region容量的一半)。
*可以建立可预测的停顿时间模型
*采用 标记-整理(整体)+标记-复制(局部)算法
步骤:
-初始标记 (停顿)
仅仅只是标记一下与GCroot直接关联的对象,并且修改TAMS指针的值,使下一阶段用户线程并发时能正确的再可用的Region中分配新对象
-并发标记
从GCroot开始对堆对象进行可达性分析,递归扫描整个对象图,找出可回收对象,还要重新处理SATB记录下再并发时有引用变动的对象
-最终标记(停顿)
对用户线程做短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录
-筛选回收(停顿 涉及到存活对象的移动)
负责更新Region的统计数据,对每个Region的回收价值和成本进行排序,根据用户所期望的暂停时间,自由选择任意多个Region组成回收集合,把决定回收的那一部分Region中的存活对象复制到另一个空的Region中去,然后清除整个Region集合。