一、垃圾回收器
1.Serial 年轻代 串行回收器,采用的是复制回收算法 ,单线程的
2.PS(Parallel Scavenge) 年轻代 并行回收器,采用的是复制回收算法,多线程的
3.ParNew 年轻代,配合CMS的并行回收,采用的是复制回收算法,多线程的
4.Serial Old 老年代,串行回收器,采用的是标记整理回收算法,单线程的
5.Parallel Old 老年代,并行回收器,采用的是标记整理回收算法,多线程的
6.CMS 老年代 并发回收器,采用标记清除回收算法,多线程
7.G1 分代收集器,但整个内存分区不存在物理上的年轻代与老年代的区别
8.ZGC
STW(stop the world):
编译代码时为每一个方法注入safepoint(方法中循环结束的点、方法执行结束的点),
在暂停应用时,需要等待所有的用户线程进入safepoint,之后暂停所有线程,
然后进行垃圾回收。
二、查看jvm垃圾回收器
查看JVM默认的垃圾回收器
cmd命令:
java -XX:+PrintCommandLineFlags -version
结果:
jdk 1.7 1.8 默认 UseParallelGC = PS + PO 【Parallel Scavenge + Parallel Old】
三、垃圾回收器跟内存大小优化
1. serial 几十兆
2.PS 上百兆 - 几个G
3.CMS - 20G
4.G1 - 上百G
5.ZGC - 4T-16T
四、常见的垃圾回收器组合
- Serial/Serial Old
- ParNew/Serial Old:与上边相比,只是比年轻代多了多线程垃圾回收而已
- ParNew/CMS:当下比较高效的组合
- Parallel Scavenge/Parallel Old:自动管理的组合
- G1:最先进的收集器,但是需要JDK1.7update14以上
五、CMS和G1的比较
CMS:
采用多线程实现"标记-清除"算法
算法原理:
1.初始标记:需要STW,只标记GC Roots能直接关联到的对象。
2.并发标记:遍历之前标记到的关联节点, 80%的时间都耗在这里
3.重新标记:需要STW,修正并发标记期间,因用户程序继续运行导致标记产生变动的那一部分对象的标记记录。
4.并发清除:并发清除可以和用户线程一起运行,所以总体上停顿的时间非常短。 会产生浮动垃圾
缺点:
1.对CPU资源敏感。
2.无法处理浮动垃圾。
3.收集结束后会产生大量碎片。
里程碑的垃圾回收器,jdk1.4版本后期引入
因此目前任何一个JDK版本默认是CMS 并发垃圾回收是因为无法忍受STW(Stop-The-World)
单碎片化严重的时候,就会清除老奶奶出来,Serial Old,拿一个扫把一个一个扫,一个老奶奶拿个扫帚扫天安门广场,那多慢。
FGC 是老年代空间不足的时候触发,默认使用垃圾回收器是PS+PO,
G1:
三色标记+SATB;
算法原理:
- G1收集器将整个堆划分为多个大小相等的区域
- G1跟踪各个区域里面的垃圾堆积的价值,在后台维护一张优先列表,每次根据允许的收集时间,优先回收价值最大的区域,这种思路:在指定的时间内,扫描部分最有价值的region(而不是扫描整个堆内存),并回收,做到尽可能的在有限的时间内获取尽可能高的收集效率。
运作流程:
- 初始标记:标记出所有与根节点直接关联引用对象。需要STW
- 并发标记:遍历之前标记到的关联节点,继续向下标记所有存活节点。在此期间所有变化引用关系的对象,都会被记录在Remember Set Logs中
- 最终标记:标记在并发标记期间,新产生的垃圾。需要STW
- 筛选回收:根据用户指定的期望回收时间回收价值较大的对象(看"原理"第二条)。需要STW
优点:
- 停顿时间可以预测:我们指定时间,在指定时间内只回收部分价值最大的空间,而CMS需要扫描整个年老代,无法预测停顿时间
- 无内存碎片:垃圾回收后会整合空间,CMS采用"标记-清理"算法,存在内存碎片
- 筛选回收阶段:
- 由于只回收部分region,所以STW时间我们可控,所以不需要与用户线程并发争抢CPU资源,而CMS并发清理需要占据一部分的CPU,会降低吞吐量。
- 由于STW,所以不会产生"浮动垃圾"(即CMS在并发清理阶段产生的无法回收的垃圾)
总结:
1、CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用;
2、G1收集器收集范围是老年代和新生代,不需要结合其他收集器使用;
3、CMS收集器以最小的停顿时间为目标的收集器;
4、G1收集器可预测垃圾回收的停顿时间
5、CMS收集器是使用“标记-清除”算法进行的垃圾回收,容易产生内存碎片
6、G1收集器使用的是“标记-整理”算法,进行了空间整合,降低了内存空间碎片。
7.虽然G1的响应时间比CMS快,G1的吞吐量要比CMS少15%左右
六、垃圾收集器常用参数
-XX:+UseSerialGC = Serial New (DefNew) + Serial Old
小型程序。默认情况下不会是这种选项
-XX:+UseParNewGC = ParNew + SerialOld
这个组合已经很少用(在某些版本中已经废弃)
-XX:+UseConc(urrent)MarkSweepGC = ParNew + CMS + Serial Old
-XX:+UseParallelGC = Parallel Scavenge + Parallel Old
(1.8默认) 【PS + SerialOld】
-XX:+UseParallelOldGC = Parallel Scavenge + Parallel Old
-XX:+UseG1GC = G1