垃圾收集器与内存分配策略(三)
垃圾收集器
Parallel Scavenge收集器
概念
Parallel Scavenge是一个新生代收集器,使用复制算法,也是并行收集;相比于ParNew收集器不同的是:Parallel Scavenge可以设置吞吐量
吞吐量的概念
吞吐量指的是CPU运行用户代码时间与CPU消耗总时间的比值(CPU消耗总时间为用户代码运行时间+垃圾回收消耗时间)
吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)
适配老年代收集器
- Parallel Old收集器
- Serial Old收集器
参数设置
-XX:MaxGCPauseMillis:设置最大垃圾收集时间,大于0的毫秒数
这个参数并不是设置越小越好,一旦设置太小,会导致收集器更加频繁的触发GC,导致收集器的吞吐量下降
-XX:GCTimeRatio:设置最大垃圾收集时间,占程序运行总集时间的比率,设置值m为0
Serial Old收集器
概念
Serial Old收集器是Serial老年代收集器;当然它也是作为一个单线程收集器存在的,一般来说只在虚拟机Client模式下选择
适配收集器
- 可以适配新生代Serial收集器使用
- 可以适配新生代Parallel Scavenge收集器使用
- 可以组合老年代CMS一起使用
使用算法
使用标记-整理算法
Parallel Old收集器
概念
作为Parallel Scanvenge收集器的老年代收集器,也是作为一个注重吞吐量的收集器
搭配收集器
- 只能搭配Parallel Scavenge新生代收集器;但是在大多数单核CPU下Parallel Scavenge收集器发挥的性能不一定比Serial收集器强
==CMS(Concurrent Mark Sweep)收集器==
概念
CMS收集器是一个老年代收集器;目的是一种以获取最短回收停顿时间为目标的收集器
适配收集器
- 搭配Serial收集器
- 搭配ParNew收集器
- 组合Serial Old一起共同组成老年代收集器
使用算法
CMS使用“标记-清除”算法,这个算法可能导致产生大量的内存碎片
工作过程
- 第一步:初始标记:这一步任然需要“stop the world”,==耗时短(这里的耗时相比较与并发标记而言)==
- 第二步:并发标记:这一步GC线程是和用户线程同步进行的,==耗时长==
- 第三步:重新标记:这一步GC线程独占,需要“stop the world”,==耗时短==
- 第四步:并发清除:这一步GC线程和用户线程同时工作,最后回收内存
优点
“stop the world”时间短,大部分时间都是并发执行的
缺点
- ==由于采用了“标记-清除”算法可能导致产生内存碎片==;在产生大量的内存碎片的时候,那么导致无法为大对象找到合适的内存空间,那么就不得不进行Full GC,然后压缩内存空间腾出足够大的空间给大对象分配内存,这个过程是无法并发的
- ==CMS收集器堆CPU资源非常依赖==,因为CMS默认开启线程数量为:(CPU数量+3)/ 4,也就是说CPU数量在4个以上,至少占用了一个CPU作为GC线程使用;4个以下时,JVM提供了一种“增量式并发收集器”,大致思想就是用户线程和GC线程抢占CPU使用权限,但是这样导致GC时间增加,吞吐量下降
- ==CMS无法处理浮动垃圾(指的在CMS在并发清理的时候出现对象内存)==;因为CMS在并发清除的时候,必须保证剩余内存足够,所以CMS不能像其他老年代收集器一样,等到老年代内存几乎满了之后才进行GC,设置-XX:CMSInitiatingOccuancyFraction的值触发GC动作,1.5默认值为68;1.6默认值为92;这个值不能设置太高导致出现大量“Concurrent Model Failure”(因为GC触发频率太低,导致所剩下内存无法支持用户线程执行),设置太高导致GC触发频率上升
参数设置
- -XX:CMSInitiatingOccupannyFraction:这个参数用来控制触发CMS收集器进行收集动作的比例;一般来说老年代GC触发都是在老年代内存几乎满了之后,而因为CMS需要并发清除动作,所以需要提前清除;1.6默认值92,1.5默认值68
- -XX:UseCMSCompactAtFullCollection:用于内存碎片太多导致无法分配大对象Full GC开关;默认值是开启
- -XX:CMSFullGCsBeforeCompaction:用于执行设置执行多少次不进行压缩的操作;默认值是0,也就是每次进行Full GC的时候都进行压缩
Full GC和Minor GC
- Full GC(又称Major GC):指的是发生在老年代的GC动作,通常伴随着一次Minor GC;速度通常非常慢
- Minor GC:指的是发生在新生代GC动作,速度通常非常快