JVM垃圾回收器

上篇我们知道垃圾回收机制,接下来,我们具体到垃圾回收器,看看JVM到底有哪些垃圾回收器。

一.GC性能指标

不可能三角

  • 吞吐量:运行用户代码的时间占总运行时间的比例
  • 暂停时间:进行GC时,用户线程被暂停的时间(STW)
  • 内存占用:JAVA堆所占内存的大小,这一点随着硬件的发展,越来越容易实现

主要矛盾:你要暂停时间短,你就需要频繁GC。但是多次GC,会导致吞吐量低。现在标准:在保证最大吞吐量的前提下,降低暂停的时间

JVM垃圾回收器_第1张图片

二.七款垃圾回收器

  • 串行回收器:Serial,Serial Old
  • 并行回收器:ParNew,Parallel Scavenge,Parallel Old
  • 并发回收器:CMS,G1

接下来看它们几个的关系图:

JVM垃圾回收器_第2张图片

 说明:

  • 红色虚线:jdk8废弃它们2组的组合
  • 绿色虚线:jdk14弃用Parallel Scavenge和Serial Old组合
  • 青色虚线:jdk14删除CMS回收器

接下来我们分别进行讨论


Serial/Serial Old

  • 最基本,最历史悠久的回收器
  • 串行回收器,Serial使用在新生代,Serial Old使用在老年代。 新生代采用复制算法,老年代使用标记压缩算法。
  • 这种回收器只有在限定单核cpu才使用,现在已经很少使用了

JVM垃圾回收器_第3张图片


ParNew

  • 并行回收器,多核情况下比Serial的要高,单核下没有Serial高。
  • 用在新生代,采用复制算法。老年代使用Serial Old

JVM垃圾回收器_第4张图片


Parallel/Parallel Old

  • 吞吐量优先java8默认的垃圾收集器
  • Parallel采用复制算法,Parallel Old采用标记压缩算法
  • Parallel与ParNew不同的是,Parallel目的为了达到一个可控的吞吐量,具有自适应调解策略
    • -XX:+UseAdaptiveSizePolicy: 开启自适应调节策略,年轻代的大小,eden,s的比例,,晋升老年代等参数会自动调节。在手动调优比较困难的情况下,可以开启这种模式
  • 适用于后台运算而不需要太多交互的任务。比如批量处理,订单处理,工资支付,科学计算等

JVM垃圾回收器_第5张图片

 三.CMS回收器
  • CMS (Concurrent-Mark-Sweep)
  • 低延迟(低暂停时间),第一款并发回收器,但不代表没有STW

CMS的回收过程:CMS回收器的过程要比其他的都复杂,主要分为四个阶段:

  • 初始标记:只标记GC Roots直接关联的对象。产生STW
  • 并发标记:从GC Roots直接关联的对象开始,向下遍历对象图。不产生STW
  • 重新标记:为了修正在并发标记期间,用户线程产生的新的对象。产生STW
  • 并发清除:标记-清除。不产生STW

总结:在初始标记重新标记阶段都会暂停用户线程,产生STW,但是STW的时间很短。 其他阶段都是并发进行,不产生STW。所以CMS虽然是并发垃圾回收器,但是整体上还是会产生 STW,只是说STW的时间较短。因为最费时的并发标记与清除标记都不需要暂停工作,所以整体 上的低暂停时间的

JVM垃圾回收器_第6张图片


CMS的缺点

  • 采用标记-清除算法会产生内存碎片
  • 对CPU资源敏感,CPU数量少会导致用户程序执行速度降低较多。
  • 产生浮动垃圾,浮动垃圾就是在并发标记阶段产生的新垃圾。虽然重新标记可以标记一些新产生的垃圾,但是对于GC Roots直接引用的对象(比如new),没有办法进行标记。

那为什么不适应标记-压缩算法?

  • 因为在并发清除的时候,用户线程没有暂停。如果使用标记整理算法,就需要移动用户线程在内存中的位置。要保证用户线程正常使用,前提是它运行的资源不受影响, 所以必须在STW情况下,才可以进行整理。     

总结:关于内存碎片虽然也可以设置整理算法解决,但是效果不好。垃圾回收过程中,必须暂停用户线程的时间。 而现在CMS要进行并发,那么就导致垃圾回收过程中,用户线程还在制造新的垃圾的现象。 所以CMS后来被移除掉了,就是因为它为了达到低延迟,牺牲了太多东西,也造成了太多的问题。 jdk9.0被移除,但是还可以用。会报错 。jdk14.0就彻底的被清除了。

四.G1垃圾回收器
  • 分区回收器并行与并发,同时还是分代收集(兼顾老年代和年轻代)。
  • 将内存分为不同的区域(Region),在可控制的延迟时间下(让垃圾回收控制在一个时间段内),优先回收垃圾量最大的区域。 在延迟可控的情况下,尽可能获得高吞吐量。(想着把吞吐量和暂停时间都尽可能的兼顾)
  • 主要是依靠的特色为:分区的原因,回收的范围小。 而且G1会把这些region放在一个优先列表中,每次垃圾回收,会在指定的时间内,收集最有价值的region区域。 达到高效的收集。
  • Region之间是复制算法,整体上可以看作是标记压缩算法

JVM垃圾回收器_第7张图片

 

 

寄语:坚持也是一种超能力

你可能感兴趣的:(JVM垃圾回收器)