Java虚拟机之垃圾回收器

  上面有7类垃圾回收器,分为两块,上面为新生代(Young generation)回收器,下面是老年代(Tenured generation)回收器。如果两个回收器之间存在连线,就说明它们可以搭配使用。

  • GC主要分二类:新生代GC和老年代GC;
  • 新生代GC包括:串行GC、并行GC、并行回收GC;
  • 老年代GC包括:老年代串行GC、老年代并行GC、CMS;
  • G1比较特殊,同时支持新生代和老年代。
1、Serial回收器(串行GC)

  它是一个新生代回收器,单线程执行,使用复制算法。它在进行垃圾回收时,必须暂停其它所有的工作线程(用户线程)。是JVM client模式下默认的新生代回收器。对于限定单个CPU的环境来说,Serial回收器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程回收效率。温馨提示,它进行垃圾收集时,必须暂停其它所有的工作线程(Stop-The-World:将用户正常工作的线程全部暂停掉),直到它收集结束。

2、ParNew回收器(并行GC)

  并行GC是Serial回收器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为与Serial回收器一样。

  它是运行在server模式下的首选新生代回收器,除了串行GC外,目前只有它能与CMS回收器配合工作。CMS回收器是一个被认为具有划时代意义的并发回收器,因此如果有一个垃圾回收器能和它一起搭配使用让其更加完美,那这个回收器必然也是一个不可或缺的部分了。

3、Parallel Scavenge回收器(并行回收GC)

  scavenge [ˈskævɪndʒ] 清除污物,打扫。并行GC的plus版,更加关注吞吐量。目标是达到一个可控制吞吐量的回收器。

  并行回收GC也是一个新生代回收器,它也是使用复制算法的回收器,又是并行多线程回收器。

  停顿时间和吞吐量不可能同时调优。我们一方买希望停顿时间少,另外一方面希望吞吐量高,其实这是矛盾的。因为:在GC的时候,垃圾回收的工作总量是不变的,如果将停顿时间减少,那频率就会提高;既然频率提高了,说明就会频繁的进行GC,那吞吐量就会减少,性能就会降低。

  吞吐量:CPU用于用户代码的时间/CPU总消耗时间的比值,即=运行用户代码的时间/(运行用户代码时间+垃圾收集时间)。比如,虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。

  jdk8中,JVM使用的默认的垃圾回收器是UseParallelGC,即新生代并行回收GC和老年代(Ps MarkSweep)组合。

4、Serial Old回收器(老年代串行GC)

  Serial Old是Serial回收器的老年代版本,它同样使用一个单线程执行收集,使用“标记-整理”算法。主要使用在Client模式下的虚拟机。

5、Parallel Old回收器(老年代并行GC)

  老年代并行GC是并行GC的老年代版本,使用多线程和标记-整理算法。

6、G1回收器

  G1(Garbage First)回收器是当今回收器发展的最前沿成果之一,自JDK 7提供的一个新回收器,基于“标记-整理”算法实现,故不会产生内存碎片。还有一个特点之前的回收器进行收集的范围都是整个新生代或老年代,而G1将收集整个Java堆(包括新生代,老年代)。

  充分利用多CPU、多核环境下的硬件优势来缩短垃圾收集的停顿时间。G1 回收器是针对性地对Java堆内存区域进行垃圾收集,而非每次都对整个 Java 堆内存区域进行垃圾收集。

  使用的垃圾收集算法:

  • 对于新生代:复制算法;
  • 对于老年代:标记 - 整理算法。
7、CMS回收器(并发GC)

  CMS回收器(Concurrent Mark Sweep:并发标记清除)基于标记-清除算法,是一种以获取最短回收停顿时间为目标的回收器。适合应用在互联网或者B/S系统的服务器上,这类应用尤其重视服务器的响应速度,希望系统停顿时间最短。

  CMS回收器的优点:并发收集、低停顿,但是CMS还远远达不到完美。

  三个显著缺点:

  • CMS回收器对CPU资源非常敏感。在并发阶段,虽然不会导致用户线程停顿,但是会占用CPU资源而导致引用程序变慢,总吞吐量下降。CMS默认启动的回收线程数是:(CPU数量+3) / 4。
  • CMS回收器无法处理浮动垃圾。
  • 会产生大量碎片。
Reference
posted @ 2021-04-17 21:16  楼兰胡杨  阅读(215)  评论(0编辑  收藏  举报