【Java】JVM垃圾回收器

2021/9/9 20:37:00

本文主要是介绍【Java】JVM垃圾回收器,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

java的垃圾回收器有好几种,除了G1之外,其他垃圾收集器都需要相互配合。这边主要关注于CMS以及G1。

参考:https://www.jianshu.com/p/3eeaee1c34bd

JDK1.7之后,提供的垃圾收集器。

在这里插入图片描述

1.CMS垃圾收集器

CMS是一种以获取最短回收停顿时间的收集器。

1.1 回收流程

在这里插入图片描述

  • 初始标记:对与GC Roots直接相连的对象进行标记,该过程需要STW,但时间非常短。
  • 并发标记:在并发过程中进行GC RootsTracing。
  • 重新标记:对之前标记过但因并发过程中发生变化的对象进行标记(注意该过程不会再标记因并发而没有标记的对象),该过程需要STW,且时间长于初始标记。
  • 并发清除:即清除。

1.2 优缺点分析

优点

  • 并发收集(GC过程中,主要的时间花费在并发标记中,所以总体上可以看作一个并发收集器)
  • 低停顿

缺点

  • 对CPU资源敏感:在GC过程中会占用一部分线程,导致程序变慢,默认的回收线程数是(CPU核数 + 3) / 4,所以在多核情况下,效率还不错,但如果是双核,则会占去一半的CPU资源。
  • 产生内存碎片:CMS是一款标记清除回收器,所以在GC中会产生大量的内存碎片。这往往会使得老年代有大量空间剩余时,无法分配大对象,不得不提前触发Full GC。对于该问题CMS收集器提供了开关参数-XX:+UseCMSCompactAtFullCollection (默认即开启),以及参数-XX:+UseCMSCompactAtFullCollection,表示在多少次不压缩的Full GC之后,做一次压缩的(默认值是0,即每次进入Full GC都进行碎片整理)。内存整理过程是无法并发的,故这会拉长停顿时间。
  • 无法处理浮动垃圾:浮动垃圾即因并发过程而没有标记到的需要回收的对象。浮动垃圾的存在意味着需要在老年代未满的时候进行回收,需要预留一部分空间。参数-XX:CMSInitiatingOccupancyFraction就表明了在老年代内存占了多少时,进行回收。要是在CMS运行期间所预留的空间无法满足程序需要,就会出现Concurrent Mode Failure,这是CMS回收器会被退化为Serial Old回收器。

Concurrent Mode Failure

CMS收集器特有的错误,指的是CMS垃圾清理核引用线程并行执行时,因老年代空间不足以分配对象时发生的错误。

2.G1垃圾回收器

G1回收器是一个优秀的垃圾回收器,在JDK 14中为默认垃圾回收器。

2.1 特点分析

在这里插入图片描述

  • 并行与并发:是一个并发的收集器。
  • 分代收集:虽然不需要与其他垃圾收集器配合,但G1仍保留了分代的概念。且G1中为存在时间不长的大对象专门开辟了一个叫 Humongous region,如果一个Humongous region无法存下这个大对象,则会使用连续的若干个区域来存储。这是为了避免在老年代区域进行平凡的回收。
  • 空间整合:从整体上,G1是一个标记整理算法,局部上(两个region之间)是复制算法。这都意味着不会产生内存碎片,在分配大对象时不会出现无法找到连续内存而引发GC。
  • 可预测的停顿:G1相对于CMS的另一大优势,G1可以指定在长度为M毫秒的时间段内,回收的时间不超过N。(G1会尽最大程度保证,90%以上)

2.2 回收流程

  • 初始标记
  • 并发标记
  • 最终标记
  • 筛选回收

总的来说,G1在大内存应用上比CMS会好一点。



这篇关于【Java】JVM垃圾回收器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程