前言

在上一篇,我们谈到了JVM中的常用垃圾回收算法,并了解了JVM中针对堆区中不同的分代采用不同的垃圾回收算法

在了解了垃圾回收算法之后,很多伙伴不禁在想,既然是分代垃圾回收,自然新生代和老年代的垃圾收集器也是不同的,事实上确实是这样,分代的回收算法也产生了不同的垃圾收集器,先来看一下下面这张简图


左边表示年轻代中可选的垃圾收集器,右边表示老年代中可选的垃圾收集器,任何两个连线之间的两种垃圾收集器可以进行组合使用,在年轻代中,Parallel Scavenge 是默认的GC收集器,而在老年代中,SerialOld为默认的GC收集器

上面的看到的年轻代和老年代收集器属于分代收集器,在JDK1.8中,由于采用了分代垃圾回收,故使用分代垃圾收集器进行GC,各个垃圾收集器根据自身的特点都有着不同的使用场景,下面针对各个垃圾收集器进行简单的说明,以便深入理解各款垃圾收集器的使用原理

可以使用下面的命令查看本机或者虚拟机上的JVM的垃圾收集器(默认安装的JDK版本)

java -XX:+PrintCommandLineFlags -version

新生代垃圾收集器

Serial

Serial垃圾收集器也叫做串行收集器,串行垃圾收集器的特点:

  • 使用单线程对垃圾对象进行GC
  • 用于年轻代的垃圾收集器
  • 适合单核CPU
  • 执行效率较低,STW时间较长(其间将会产生较长的GC等待时间)
  • 适用于垃圾较小的内存场景(几十MB)
  • 主流虚拟机已淘汰


ParNew

这是对单线程的Serial的一种改进,ParNew收集器是并行的,在多CPU的场景下会有比串行收集器更好的性能,除此之外,实现算法跟Serial完全一样

ParNew垃圾收集器特点:

  • JDK8之后默认的年轻代垃圾收集器
  • STW短时优先,GC次数多(但是总体保证每次GC时间较短)
  • 使用多个线程(默认情况下与CPU核数一致)并行GC,效率提升
  • 适合多核CPU
  • 适用于较大的内存对象场景
  • 适合与用户交互的场景
  • 一般与CMS配合使用


Parallel Scavenge

也称作PS收集器,这也是一种新生代垃圾收集器,它采用的也是复制算法,与前两种收集器最大的区别是,它关注的是吞吐量而不是延迟,也被称为是吞吐量优先的收集器

其特点为:

  • 以追求吞吐率最小(每一次GC消耗的时间 / 总时间)优先
  • JDK1.8默认的垃圾收集器(年轻代)
  • STW时间长,GC次数少(目前Java应用的部署的服务器更多的是进行后台任务的计算,直接与用户交互的过程较少,因此减少GC次数就很有必要)
  • 多线程GC,执行效率较高
  • 适合多核CPU
  • 适合后台计算任务

老年代垃圾收集器

SerialOld

这个是jdk1.2以前的默认收集器,适合单线程下作为CMS的备用收集器,由于运行效率较低,目前基本上很少使用,其运行原理和年轻代的Serial相似


Parallel Old

该收集器可以理解为PS收集器的老年代版本(对比理解PS收集器),其主要特点包括:

  • 关注吞吐率
  • STW时间较长,GC次数少
  • 多线程GC,执行效率较高
  • 适合多线程CPU
  • 适合后台计算任务


CM

CMS,Concurrent Mark Sweep,这是一款真正的并发收集器,属于老年代的垃圾收集器中最复杂的一款垃圾收集器,其主要特点为:

  • 用户线程与GC并行执行(前面的收集器是用户线程和垃圾回收线程是不同的线程,因此STW时间相对较长),用户的感知最小
  • 超短的STW,适合较大的内存环境(几十G)
  • 会产生浮动垃圾
  • 会产生标记失败
  • 会降低用户线程的CPU使用效率(CPU需要分出部分的线程同时处理垃圾回收,以至CPU不能全部用户用户线程的任务处理)
  • 标记清除时产生大量内存碎片(CMS采用标记清除算法)
  • JDK14被废弃

从上图中我们发现,CMS垃圾回收器在执行一次完整的垃圾回收时要经历几个阶段:初始标记(会产生一个很短的STW) ,并发标记,重新标记,并发清理,对其中的几个关键点做简单的说明:

  • 初始标记:只标记GCRoot第一层关联
  • 浮动垃圾:运行中未及时发现的垃圾对象,会在重新标记阶段进行标记(由于用户线程和GC线程是并发执行的)
  • 标记失败:被认定的垃圾对象在后面的阶段中再次被引用,在重新标记阶段修正
  • 并发清理:会针对前面产生的各种垃圾对象,并发标记和重新标记阶段中的那些垃圾对象在并发清理阶段完成一次真正意义上的回收,此时用户线程将会处于暂停的状态(实际产生的情况很少)

在实际工作中如何通过参数设置进行搭配使用呢?可以参考下面的表格

新生代 老年代 JVM参数
Serail SerialOld -XX:+UseSerialGC
Parallel Scavenge SerialOld -XX:+UseParallelGC
Parallel Scavenge ParallelOld -XX:+UseParallelOldGC
ParNew SerialOld -XX:+UseParNewGC
ParNew CMS + SerailOld -XX:+UseConcMarkSweepGC
G1 G1 -XX:+UseG1GC

如果想要自定义自己的应用使用某种收集器,以springboot的jar包为例,可以使用下面的命令:

java -jar -XX:+UseParallelGC XXX.jar

以上是关于分代垃圾收集器中,新生代和老年代各款收集器的说明,但是随着JVM的持续迭代与优化,垃圾收集器也在持续完善,比如JDK9开始就出现了不分代垃圾收集器,像CMS收集器,在JDK14中被废弃,说明了在迭代中,有更好的收集器取代它,下面再介绍几种常用的不分代垃圾收集器

不分代垃圾收集器

常用的不分代垃圾收集器包括下面几种

  • G1收集器
  • ZGC收集器
  • Shenandoah收集器

G1收集器

G1收集器,是比前面的更优秀,真正有突破的一款垃圾收集器,在G1中还是保留了分代的概念,是实际上已经在新生代和老年代中没有物理隔离了,在G1中,内存空间被分割成一个个的Region区,所谓新生代和老年代,都是由一个个region组成的,同时G1也不需要跟别的收集器一起配合使用,自己就可以搞定所有内存区域。整体上来讲不是一个分代收集器,是一个通吃收集器。这也是JVM内存管理和垃圾收集的一个发展趋势。从后面zgc中我们可以更清晰的看到这个变化

G1采用了标记-整理算法,避免了CMS中的内存碎片问题,另外它能达到可控的垃圾时间

整体来说,G1收集器的特点:

  • JDK1.9默认的垃圾收集器
  • 多线程并发标记,并发回收
  • 物理分区(Region),1/2/4/8/32mb(即在物理存储上,不再像分代那样有明确的分代概念,提供了这几种大小规格进行选择)
  • 逻辑分代,物理分区
  • GC时间极短,单次STW的时间默认最多200MS
  • 支持上百G的内存GC

    G1垃圾回收过程可以和CMS垃圾回收过程进行类比,可以认为是G1收集器吸收了CMS的某些优秀的特点并进行了改良,但在其内部,仍然是以分代的思想进行垃圾回收,即采用了: 新生代 + 老年代 的混合回收算法(Mixed GC),触发条件为:老年代超过了堆内存的45%

ZGC

zgc是jdk11中要发布的最新垃圾收集器,不管是CMS收集器,还是G1收集器(尽管物理上没有分代的概念,但是逻辑上仍然采用了分代的思想进行垃圾回收),都有一个特点,就是在整个垃圾收集过程中的初始标记最终标记阶段,会有一个STW的产生,尽管G1相比CMS有了更大的提升,但是由于分代的概念存在,始终无法绕过这个问题

ZGC特点:

  • JDK11出现的实验性的GC,OracleJDK中使用
  • <10ms的STW时间
  • 分区容量可动态规划,小的region - 2MB,中 - 32MB(根据对象大小的不同开辟不同Region大小的内存块)
  • 支持T级别的内存GC
  • 彻底不分代,利用染色指针实现对象引用
  • 在GC的标记压缩回收对象过程中与用户线程并发执行,但是过程中并不产生STW


Shenandoah收集器

Shenandoah收集器目前在JDK12中也处于实验性阶段,其主要特点包括:

  • 一款实验性的GC,OpenJDK中使用
  • <10ms的STW时间
  • 固定大小内存块,彻底不分代
  • 支持T级别的内存GC
  • 利用读屏障与转发指针实现对象的动态引用
  • 在GC的标记压缩与回收对象过程中与用户线程并发执行,过程中不再产生STW


后面两种收集器可以作为学习进行了解,尽管目前还没有大规模的投入商用,但是其设计理念却为未来的垃圾收集器的持续优化和改进提供了很好的思路和方向,尤其是ZGC 和Shenandoah的超低延迟STW,可以说在分代收集器的基础上进行了相当大的提升,让我们拭目以待吧

本篇到此结束,最后感谢观看!

JVM常用垃圾收集器相关推荐

  1. JVM(四)--垃圾收集器

    JVM(四)–垃圾收集器 这篇博客的内容包括: 一.垃圾收集器: 1,Serial 收集器: 2,ParNew 收集器: 3, Parallel Scavenge 收集器: 4,Serial Old收 ...

  2. 深入理解JVM - ZGC垃圾收集器

    如果下面的一些概念有些不清楚的可以先看深入理解JVM - 垃圾收集器和深入理解JVM - Shenandoah垃圾收集器. ZGC(Z Garbage Collector)是一款由Oracle公司研发 ...

  3. JVM之垃圾收集器回收种类

    JVM之垃圾收集器回收种类 目录 面试常见问题 串行并行并发G1四大垃圾回收方式 如何查看默认的垃圾收集器 JVM默认的垃圾收集器有哪些 GC之7大垃圾收集器详解 1. 面试常见问题 GC垃圾回收算法 ...

  4. Android中JVM七大垃圾收集器【解析】

    概述 GC垃圾收集器的种类 新生代:年轻代用来存放最近创建的对象 老年代:主要存放应用程序中生命周期长的内存对象 永久代:内存的永久保存区域(类和元数据),GC不参与回收 Serial收集器:串行收集 ...

  5. jvm(3)-垃圾收集器与内存分配策略

    [0]README 0.1)本文部分文字转自:深入理解jvm,旨在学习 垃圾收集器与内存分配策略 的基础知识: [1]垃圾回收概述 1)GC(Garbage Collection)需要完成的3件事情: ...

  6. JVM优化系列-JVM G1 垃圾收集器

    导语   G1回收器是在JDK1.7中正式使用的一种全新的垃圾回收器,它的目标是为了取代CMS回收器.G1回收器拥有独特的垃圾回收策略,和之前的任意的一种垃圾回收器都有所不同,但是从分代策略上来说依然 ...

  7. JVM常见垃圾收集器

    (1) 串行收集器 Serial:Serial.Serial Old -XX:+UseSerialGC -XX:+UseSerialOldGC (2) 并行收集器 Parallel:Parallel ...

  8. Java虚拟机(jvm)——垃圾收集器与内存分配策略

    文章目录 判断对象的存活 引用和对象死亡 4 种引用 宣告对象死亡 回收方法区 垃圾回收算法 标记清除算法: 标记复制算法: 标记整理算法 分代收集算法: 增量收集算法 一些相关的概念: System ...

  9. JVM篇·垃圾收集器与内存分配策略

    Java堆内存的整理方法 本文为<深入理解Java虚拟机_第三版 周志明>学习笔记 引用计数法 概念:在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1,当引用失效时,计数 ...

最新文章

  1. 微信小程序获取手机系统信息
  2. SWFUpload上传文件组件,跨域上传文件
  3. 【3006】统计数字
  4. centos打显卡驱动命令_CentOS7显卡驱动问题
  5. export和export default的区别
  6. 给定条件找最小值c语言程序_根据给定条件最小化n的最小步骤
  7. java 验证码 添加背景图_java登陆界面怎么加背景图 会的我加你
  8. ehcache springboot_Spring Boot 入门示例合集(附源代码)
  9. access通过身份证号提取性别_从身份证号码中提取出生年月,性别等都不掌握,那就真的Out了...
  10. html 宽度单位,长度单位有哪些?
  11. 葛道辉,李洪升,张亮,等. 轻量级神经网络架构综述
  12. Chromium 文件下载
  13. optaplanner学习笔记(十)约束配置:动态调整约束权重
  14. 关于地图开发的那些坑儿
  15. 华为、字节跳动、蔚来、康师傅、法雷奥、AIG等公司高管变动
  16. MTK平台ota升级后不删除u盘的update.zip
  17. 与高校同行,华为人工智能课程套件揭秘 | 华为昇腾师资培训沙龙成都场
  18. 編程之美﹣電梯調度算法
  19. 快速进化 | 新一代科学计算软件 MWORKS.Syslab 2022b 更新发布
  20. python经典好书-Python 必读好书,这十本分量十足!

热门文章

  1. ORACLE获取某个时间段之间的月份列表和日期列表
  2. 【转】Cache Buffer Chain 第二篇
  3. CSS 全解析实战(一)-导读
  4. Idea创建简单Java Web项目并部署Servlet
  5. Protocol Buffers 学习(6):文件 | 字段选项介绍
  6. MySQL内核月报 2015.01-MySQL · 捉虫动态· replicate filter 和 GTID 一起使用的问题
  7. KVM之初体验——QEMU安装虚拟机
  8. 谷歌将于11月修改服务条款
  9. Servlet中参数获取方法
  10. WPF、Authorware和Flash