在前面,我们已经了解了JVM的分代收集,知道JVM垃圾收集在新生代主要采用标记-复制算法,在老年代主要采用标记-清除和标记-整理算法。接下来,我们看一看JDK默认虚拟机HotSpot的一些垃圾收集器的实现。

1、常见垃圾回收器

首先来看一下JDK 11之前全部可用的垃圾收集器。

图中列出了七种垃圾收集器,连线表示可以配合使用,所在区域表示它是属于新生代收集器或是老年代收集器。

这里还标出了垃圾收集器采用的收集算法,G1收集器比较特殊,整体采用标记-整理算法,局部采用标记-复制算法,后面再细讲。

1.1、Serial收集器

Serial收集器是最基础、历史最悠久的收集器。

如同它的名字(串行),它是一个单线程工作的收集器,使用一个处理器或一条收集线程去完成垃圾收集工作。并且进行垃圾收集时,必须暂停其他所有工作线程,直到垃圾收集结束——这就是所谓的“Stop The World”。

Serial/Serial Old收集器的运行过程如图:

1.2、ParNew收集器

ParNew收集器实质上是Serial收集器的多线程并行版本,使用多条线程进行垃圾收集。

ParNew收集器的工作过程如图所示:

这里值得一提的是Par是Parallel(并行)的缩写,但需要注意的是,这个并行(Parallel)仅仅是描述同一时间多条GC线程协同工作,而不是GC线程和用户线程同时运行。ParNew垃圾收集也是需要Stop The World的。

1.3、Parallel Scavenge收集器

Parallel Scavenge收集器是一款新生代收集器,基于标记-复制算法实现,也能够并行收集。和ParNew有些类似,但Parallel Scavenge主要关注的是垃圾收集的吞吐量。

所谓吞吐量指的是运行用户代码的时间与处理器总消耗时间的比值。这个比例越高,证明垃圾收集占整个程序运行的比例越小。

Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量:

  • -XX:MaxGCPauseMillis,最大垃圾回收停顿时间。这个参数的原理是空间换时间,收集器会控制新生代的区域大小,从而尽可能保证回收少于这个最大停顿时间。简单的说就是回收的区域越小,那么耗费的时间也越小。

    所以这个参数并不是设置得越小越好。设太小的话,新生代空间会太小,从而更频繁的触发GC。

  • -XX:GCTimeRatio,垃圾收集时间与总时间占比。这个是吞吐量的倒数,原理和MaxGCPauseMillis相同。

由于与吞吐量关系密切,Parallel Scavenge收集器也经常被称作“吞吐量优先收集器”。

1.4、Serial Old收集器

Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用标记-整理算法。

Serial Old收集器的工作过程如图:

1.5、Parallel Old收集器

Parallel Old是Parallel Scavenge收集器的老年代版本,支持多线程并发收集,基于标记-整理算法实现。

1.6、CMS收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,同样是老年代的收集齐,采用标记-清除算法。

CMS收集齐的垃圾收集分为四步:

  • 初始标记(CMS initial mark):单线程运行,需要Stop The World,标记GC Roots能直达的对象。
  • 并发标记((CMS concurrent mark):无停顿,和用户线程同时运行,从GC Roots直达对象开始遍历整个对象图。
  • 重新标记(CMS remark):多线程运行,需要Stop The World,标记并发标记阶段产生对象。
  • 并发清除(CMS concurrent sweep):无停顿,和用户线程同时运行,清理掉标记阶段标记的死亡的对象。

涉及到了多次标记的过程,这里插入一点三色抽象的知识。三色抽象用来描述对象在垃圾收集过程中的状态。

通常白色代表对象未被扫描到,灰色表示对象被扫描到但未被处理,黑色表示对象及其后代已被处理。在CMS的标记和清除过程中就用到了这种抽象,详细的可以查看参考【5】。

Concurrent Mark Sweep收集器运行示意图如下:

优点:CMS最主要的优点在名字上已经体现出来——并发收集、低停顿。

缺点:CMS同样有三个明显的缺点。

  • Mark Sweep算法会导致内存碎片比较多

  • CMS的并发能力比较依赖于CPU资源,并发回收时垃圾收集线程可能会抢占用户线程的资源,导致用户程序性能下降。

  • 并发清除阶段,用户线程依然在运行,会产生所谓的理“浮动垃圾”(Floating Garbage),本次垃圾收集无法处理浮动垃圾,必须到下一次垃圾收集才能处理。如果浮动垃圾太多,会触发新的垃圾回收,导致性能降低。

1.7、Garbage First收集器

Garbage First(简称G1)收集器是垃圾收集器的一个颠覆性的产物,它开创了局部收集的设计思路和基于Region的内存布局形式。

虽然G1也仍是遵循分代收集理论设计的,但其堆内存的布局与其他收集器有非常明显的差异。以前的收集器分代是划分新生代、老年代、持久代等。

G1把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间。收集器能够对扮演不同角色的Region采用不同的策略去处理。

这样就避免了收集整个堆,而是按照若干个Region集进行收集,同时维护一个优先级列表,跟踪各个Region回收的“价值,优先收集价值高的Region。

G1收集器的运行过程大致可划分为以下四个步骤:

  • 初始标记(initial mark),标记了从GC Root开始直接关联可达的对象。STW(Stop the World)执行。

  • 并发标记(concurrent marking),和用户线程并发执行,从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象、

  • 最终标记(Remark),STW,标记再并发标记过程中产生的垃圾。

  • 筛选回收(Live Data Counting And Evacuation),制定回收计划,选择多个Region 构成回收集,把回收集中Region的存活对象复制到空的Region中,再清理掉整个旧 Region的全部空间。需要STW。

相比CMS,G1的优点有很多,可以指定最大停顿时间、分Region的内存布局、按收益动态确定回收集。

只从内存的角度来看,与CMS的“标记-清除”算法不同,G1从整体来看是基于“标记-整理”算法实现的收集器,但从局部(两个Region 之间)上看又是基于“标记-复制”算法实现,无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,垃圾收集完成之后能提供规整的可用内存。

2、前沿垃圾回收器

2.1、ZGC收集器

在JDK 11当中,加入了实验性质的ZGC。它的回收耗时平均不到2毫秒。它是一款低停顿高并发的收集器。

与CMS中的ParNew和G1类似,ZGC也采用标记-复制算法,不过ZGC对该算法做了重大改进:ZGC在标记、转移和重定位阶段几乎都是并发的,这是ZGC实现停顿时间小于10ms目标的最关键原因。

ZGC虽然在JDK 11还处于实验阶段,但由于算法与思想是一个非常大的提升,未来前景相信还是很广阔的。

3、垃圾收集器选择

3.1、收集器选择权衡

垃圾收集器的选择需要权衡的点还是比较多的——例如运行应用的基础设施如何?使用JDK的发行商是什么?等等……

这里简单地列一下上面提到的一些收集器的适用场景:

  • Serial :如果应用程序有一个很小的内存空间(大约100 MB)亦或它在没有停顿时间要求的单线程处理器上运行。
  • Parallel:如果优先考虑应用程序的峰值性能,并且没有时间要求要求,或者可以接受1秒或更长的停顿时间。
  • CMS/G1:如果响应时间比吞吐量优先级高,亦或垃圾收集暂停必须保持在大约1秒以内。
  • ZGC:如果响应时间是高优先级的,亦或堆空间比较大。

3.1、设置垃圾收集器

设置垃圾收集器(组合)的参数如下:

新生代 老年代 JVM 参数
Incremental Incremental -Xincgc
Serial Serial -XX:+UseSerialGC
Parallel Scavenge Serial -XX:+UseParallelGC -XX:-UseParallelOldGC
Parallel New Serial N/A
Serial Parallel Old N/A
Parallel Scavenge Parallel Old -XX:+UseParallelGC -XX:+UseParallelOldGC
Parallel New Parallel Old N/A
Serial CMS -XX:-UseParNewGC -XX:+UseConcMarkSweepGC
Parallel Scavenge CMS N/A
Parallel New CMS -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
G1 -XX:+UseG1GC

参考:

【1】:周志朋编著《深入理解Java虚拟机:JVM高级特性与最佳实践》

【2】:《垃圾回收算法手册 自动内存管理的艺术》

【3】:Garbage Collection in Java – What is GC and How it Works in the JVM

【4】:Java Hotspot G1 GC的一些关键技术

【5】:GC Algorithms: Implementations

【6】:新一代垃圾回收器ZGC的探索与实践

【JVM进阶之路】七:垃圾收集器盘点的更多相关文章

  1. JVM性能优化系列-(2) 垃圾收集器与内存分配策略

    2. 垃圾收集器与内存分配策略 垃圾收集(Garbage Collection, GC)是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如 ...

  2. java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...

  3. JVM学习笔记三:垃圾收集器与内存分配策略

    内存回收与分配重点关注的是堆内存和方法区内存(程序计数器占用小,虚拟机栈和本地方法栈随线程有相同的生命周期). 一.判断对象是否存活? 1. 引用计数算法 优势:实现简单,效率高. 致命缺陷:无法解决 ...

  4. 查看JVM使用的默认的垃圾收集器

    一.查看步骤 cmd执行命令: java -XX:+PrintCommandLineFlags -version 输出如下(举例): 针对上述的-XX:UseParallelGC,这边我们引用< ...

  5. jvm系列(三):GC算法 垃圾收集器

    原文出处:纯洁的微笑 这篇文件将给大家介绍GC都有哪几种算法,以及JVM都有那些垃圾回收器,它们的工作原理. 概述 垃圾收集 Garbage Collection 通常被称为"GC" ...

  6. Spark(八)JVM调优以及GC垃圾收集器

    一JVM结构 1 Java内存结构 JVM内存结构主要有三大块:堆内存.方法区和栈. 堆内存是JVM中最大的一块由年轻代和老年代组成,而年轻代内存又被分成三部分,Eden空间.From Survivo ...

  7. JVM垃圾回收算法 及 垃圾收集器

    摘自<深入理解Java虚拟机> 一.什么是: GC算法是 方法论,那么垃圾收集器就是具体的 实现. 二.四种 垃圾回收算法 1.标记-清除算法:最基础的收集算法:不足有两点:1标记和清除两 ...

  8. JVM 的GC算法和垃圾收集器

    1.标记清除算法 黑色部分代表可回收对象,灰色部分代表存活对象,绿色部分代表未使用的.最基础的收集算法就是标记清除算法如同他名字一样,算法分为"标记"和"清除" ...

  9. 【JVM学习笔记二】垃圾收集器与内存分配策略

    1. 概述 1) GC的历史比Java久远 2) GC需要完成的三件事: | 哪些内存需要回收 | 什么时候回收 | 如何回收 3) Java内存运行时区域各个部分: | Java虚拟机栈.计数器.本 ...

随机推荐

  1. 惠普机械键盘 K10GL 使用评测

    惠普机械键盘 GK100 使用评测 手感太差,不是 RGB 背光 惠普(HP) K10GL 机械键盘 有线 LED背光机械键盘 87键 混光青轴 refs https://item.jd.com/10 ...

  2. Apple Support

    Apple Support Send Files to Apple Support https://gigafiles.apple.com/#/customerupload refs 无法截屏 bug ...

  3. how to remove duplicates of an array by using js reduce function

    how to remove duplicates of an array by using js reduce function ??? arr = ["a", ["b& ...

  4. HTML5 Template in Action

    HTML5 Template in Action https://developer.mozilla.org/es/docs/Web/HTML/Elemento/template https://de ...

  5. awesome youtube programming video tutorials

    awesome youtube programming video tutorials youtube programming tutorials https://www.youtube.com/fe ...

  6. 智能货柜 & 技术原理 (动态视觉识别 + 重力感应)

    智能货柜 & 技术原理 (动态视觉识别 + 重力感应) 智能货柜 拥有智能化.精细化运营模式的智能货柜成为代替无人货架继前进的方式. 相比无人货架来说,智能货柜的技术门槛更高,拥有 RFID. ...

  7. how to find jobs in the website codes

    how to find jobs in the website codes X-Custom-Heade https://developer.mozilla.org/en-US/docs/Web/AP ...

  8. scrimba & interactive free online tutorials

    scrimba & interactive free online tutorials https://github.com/scrimba/community/blob/master/FAQ ...

  9. 「NGK每日快讯」11.20日NGK公链第17期官方快讯!

  10. 【DB宝19】在Docker中使用MySQL高可用之MHA

    目录 一.MHA简介和架构 1.1 MHA简介 1.2 MHA工具包的组成 1.3 MHA架构 二.准备MHA环境 2.1 下载MHA镜像 2.2 编辑yml文件,创建MHA相关容器 2.3 安装do ...