一文读懂Java七大垃圾回收器

java和c++最大的不同就是java中不需要手动去回收对象,在运行时jvm会自动帮我们进行垃圾回收,接下来让我们揭开垃圾收集器的面纱

名词解释

并行:多条线程并行工作
并发:多个线程并发执行,但他们不是并行的,有可能交交替执行
吞吐量:吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间))
GC Roots:

  1. 虚拟机栈(栈桢中的本地变量表)中的引用的对象 ;
  2. 方法区中的类静态属性引用的对象
  3. 方法区中的常量引用的对象
  4. 本地方法栈中JNI的引用的对象;

为什么要垃圾回收?

不回收你养我啊,就和我们电脑磁盘满了删除文件、房间乱了整理房间一个道理

什么时候回收垃圾?

  1. 老年代或年轻代对象满,无法存放新对象时触发GC
  2. 代码中调用System.gc(),触发Full GC,可能会连带Minor GC
  3. 程序运行的时候有一条低优先级的GC线程,它是一条守护线程,当这条线程处于运行状态的时候,自然就触发了一次GC了

垃圾收集器概览

在这里插入图片描述
图中可以看到,新生代中有三个垃圾回收器,老年代中有三个回收器,而G1既可以在新生代使用也可以在老年代使用。连接线代表可以组合使用的收集器。

各种垃圾收集器的优缺点

新生代垃圾收集器:Serial(新生代-串行-复制算法)

使用单个cpu或一条线程收集,收集时停止其它所有工作线程,直至垃圾收集完成,在Client模式下默认为新生代的垃圾收集器

使用场景:单线程的,单核/内核少的计算机来说,它的性能表现很好。简单高效
优点:高效简单
缺点:会停止其它线程

新生代垃圾收集器:ParNew(新生代-并行-复制算法)

Serial的多线程版本,线程数默认为CPU核心数,可以通过-XX:ParallelGCThreads 配置线程数,在Server模式下默认为新生代的垃圾收集器

使用场景:多核cpu,要求高效,且能接收暂时停止工作的情况
优点:能够充分发挥多核cpu作用、高效简单
缺点:会停止其它工作线程

新生代垃圾收集器:Parallel Scavenge(新生代-并行-复制算法)

主要关注点在于吞吐量,吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间))
高吞吐量可以最高效率地利用 CPU 时间,尽快地完成程序的运算任务

使用场景:交互少,计算多,适合在后台运算的场景
优点:高吞吐量,高效的利用cpu时间、自适应调节策略

老年代垃圾收集器:Serial Old(老年代-串行-标记整理算法)

Old代表老年代版本,是Client模式下默认老年代的垃圾收集器

使用场景:单核cpu情况下,充分发挥性能

老年代垃圾收集器:Parallel Old(老年代-并行-标记整理算法)

在jdk1.6才提供此收集器,主要应对老年代的高吞吐量要求,类似于新生代高吞吐量垃圾收集器Parallel Scavenge

使用场景:系统需要高吞吐量情况,建议新生代Parallel Scavenge+老年代Paralle Old
优点:高吞吐量,高效的利用cpu多核心

老年代垃圾收集器:CMS(Concurrent Mark Sweep )(老年代-并发-标记清除算法)

老年代垃圾回收器,主要目标为尽可能减少垃圾回收时的停顿时间

使用场景:最短的垃圾收集停顿时间可以为交互比较高的程序提高用户体验

优点:低停顿时间,并发标记、并发清除都无需暂停工作线程,基本可以认为垃圾回收和用户线程是一起工作的

缺点:

  1. 会产生内存碎片
  2. 浮动垃圾(Floating Garbage):由于还在运行中,在标记结束后又产生的垃圾无法在本次回收,需要等待下次GC
  3. 对CPU资源非常敏感

CMS回收器运行过程:
在这里插入图片描述

  1. 初始标记(STW):标记根对象和根节点(GC Roots)可直接关联到的对象,速度很快
  2. 并发标记:标记所有Root Tracing过程中存活的对象
  3. 预清理:清理前的准备和控制停顿时间,可以被关闭
  4. 重新标记(STW):修正并发标记期间,因用户程序继续运行而导致标记产生变动的那部分对象的标记记录。时间远比并发标记短,这也是为什么需要并发标记阶段,就是为了减少STW
  5. 并发清理:真正的执行类清理操作,清除GC Roots不可达对象
  6. 并发重置:收尾工作,重置工作

CMS回收器配置参数:
在这里插入图片描述

老少通吃垃圾收集器:G1(Garbage First Garbage Collector)(老年代+年轻代-并发-标记整理算法)

jdk1.7中引入,优先回收垃圾比例最高的区域,G1将堆划分为多个区域,每次收集部分区域来减少GC产生的停顿时间

使用场景:面向服务端应用,针对具有大内存、多处理器的机器;最主要的应用是为需要低GC延迟

优点:

  1. 可以精准控制停顿时间,不牺牲吞吐量前提下,实现低停顿垃圾回收,并具有大堆的应用程序提供解决方案
  2. 基于标记整理算法,没有内存碎片
  3. 堆内存划分为多个区域并排优先级,对垃圾多的区域优先回收,确保 G1 收集器可以在有限时间获得最高的垃圾收集效率。

运行过程:
在这里插入图片描述

阶段一:新生代GC

在这里插入图片描述
此阶段主要工作是回收Eden和survivor区。

  1. 当Eden区域满的时候,启动新生代GC
  2. 存活的对象且没有达到年龄进入To Survivor区
  3. 对于一些达到年龄的对象进入老年代
阶段二:并发标记周期(关键阶段)

在这里插入图片描述

  1. 初始标记(STW):标记出根节点和从根节点可直接到达的对象,并且会触发一次年轻代GC。
  2. 根区域扫描:扫描survivor区可以直达老年代的对象,这一过程必须在young GC之前完成。
  3. 并发标记:Root Tracing过程中所有存活对象标记,此过程可能被young GC中断。
  4. 重新标记(STW):由于并发标记阶段,应用程序也是并发的。在这个阶段会对标记结果进行最后的修正
  5. 独占清理(STW):计算各个区域的存活对象和GC回收比例,然后根据比例进行排序。目的是供混合收集使用
  6. 并发清理:去识别并清理那些完全空闲的区域
阶段三:混合收集

在这里插入图片描述

  1. 回收比例较高的区域。(分区域GC可以降低GC耗时)
  2. 新生代和老年代会同时执行。那么被清理区域中的存活对象就会被移动到其它区域。(减少内存碎片)
阶段四:Full GC

这个阶段不是必须的,G1就是为了避免Full GC产生的停顿时间。只有在G1收集过程中,发生内存不够才会触发Full GC(比如复制存活对象的时候)

G1收集器配置参数

在这里插入图片描述

为什么G1收集器可以实现可预测的停顿?
  • G1 收集器避免全区域垃圾收集,它把堆内存划分为大小固定的几个独立区域
  • 跟踪这些区域的垃圾收集进度,同时在后台维护一个优先级列表
  • 每次根据所允许的收集时间, 优先回收垃圾最多的区域**(名称Garbage-First的由来)**
  • 区域划分和优先级区域回收机制,确保 G1 收集器可以在有限时间获得最高的垃圾收
    集效率

如何判定对象是否可回收(是垃圾)

  • 引用计数法(Reference Conting)

    原理:通过分析一个对象是否有被引用,没有则认定为已死亡(内部是有一个引用计数器,一个引用+1)

    问题:如果两个对象循环引用则无法识别

    收集时机:下次垃圾收集时直接回收

  • 根搜索算法(GC Root Tracing)(可达性分析的方法)

    原理:通过一系列称为“GC Root”的点开始,向下搜索,当一个对象到GC Root没有任何引用链相连,则认定为不可达对象(这里没有立即死亡)

    收集时机:两次的标记都为不可达对象为死亡对象则为可回收对象

总结

收集器虽然有七个,单理解了java的发展历史之后也就不足为奇,比如最早的单核机器运行,就有Serial,后来有多核cpu,就有了ParNew(名字不好理解),再后来既要多线程又要停顿,就有了Parallel Scavenge,高吞吐量+高效的利用cpu时间

再再再后来,就是G1,可以独立使用,不仅老少通吃,还能不牺牲吞吐量情况下控制垃圾回收所造成的停顿时间且不产生内存碎片,目前这也是垃圾收集器理论发展的最前沿成果
在这里插入图片描述

当然,在JDK 11当中,加入了实验性质的ZGC。它的回收耗时平均不到2毫秒。它是一款低停顿高并发的收集器,但并没有实际的接触,我们用的都是JDK 1.8🤭,钉子户了哈哈哈

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我思知我在

原创不易,多多一键三连

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值