一、垃圾收集器示意图
(1)Serial收集器
(2)ParNew收集器
(3)Parallel Scavenge 收集器:使用复制算法,和ParNew的区别在于
(1) parallel scanvenge 的关键点在于它关注的是吞吐量,
吞吐量 = 用户代码运行时间 / (用户代码运行时间 + 垃圾收集时间)
而与之对比的是,CMS收集器等的关注点是尽可能缩短垃圾收集时,用户线程的停顿时间。
主要是有三个参数:
-XX:MaxGcPauserMillis:收集器尽可能保证内存回收花费时间不超过设定值,但也不是越小越好,会牺牲吞吐量和新生代空间
-XX:GCTimeRatio:吞吐量的倒数,比如 如果是 19 那么允许的最大GC时间比例为 1/(1 + 19) =5 %
-XX:+UseAdaptiveSizePolicy:不需要手动指定新生代大小,虚拟机会自动调整参数(GC自适应)
(4)Serial Old
(5)ParallelOld:配合Parallel Scavenge使用,吞吐量优先组合
(6)CMS收集器
以获取最短回收停顿时间为目标的收集器
基于标记清除算法
优势并发收集,低停顿
-
初始标记:标记GCroot直接关联到的对象
-
并发标记
-
重新标记:修正并发标记期间因用户程序继续运行导致标记产生变动的对象的标记记录
-
并发清除
缺点:
-
对CPU资源敏感,默认启动回收线程数(CPU + 3)/ 4 当CPU数量在4个一下时,如2个,CMS影响变得太大
-
无法处理浮动垃圾,也就是在并发清除的时候,由于用户线程还在运行,会产生新的垃圾,因此CMS不能等到老年代满了再进收集,需要预留空间,可以通过参数配置,提高触发gc百分比
-
CMS基于标记清除,会有大量碎片,可能出现分配大对象时明明还有空间,却找不到连续空间,提前出发fullGc。但是现在CMS提供了一个参数
-XX: +UseCMSCompactAtFullCollection开关参数,用于 在CMS收集器顶不住要进行fullgc的时候开启内存碎片的合并整理过程
(7)G1收集器
-
基于标记整理
-
G1收集器不需要其他收集器配合就可以独立管理整个GC堆
-
G1运行期间不会产生碎片
-
G1将整个堆划分为多个大小相等的独立区域,region,可以有效地避免在整个java堆中进行全区域的垃圾收集