首页 > 其他分享 >《JVM第9课》垃圾回收器

《JVM第9课》垃圾回收器

时间:2024-11-12 15:57:36浏览次数:1  
标签:标记 回收 STW 线程 垃圾 JVM GC

先来看一张图,串行代表两个垃圾回收器按顺序执行,并行代表同时执行。STW代表工作线程暂停,Stop The World的意思。

垃圾回收器 执行顺序 执行方式 作用区域 使用算法 说明
Serial GC 串行 工作线程暂停,单线程进行垃圾回收 新生代 复制算法
Serial Old GC 串行 工作线程暂停,单线程进行垃圾回收 老年代 标记-整理算法
ParNew GC 并行 工作线程暂停,多线程进行垃圾回收 新生代 复制算法 Serial GC的多线程版
CMS GC 并行 用户线程和垃圾回收线程同时执行 老年代 标记-清除算法 低暂停
Parallel GC 并行 工作线程暂停,多线程进行垃圾回收 新生代 复制算法 和ParNew相比能动态调整内存分配情况JDK8默认
Parallel Old GC 并行 工作线程暂停,多线程进行垃圾回收 老年代 标记整理算法 替代串行的Serial Old GC
G1 并行 用户线程和垃圾回收线程同时执行 整堆 分区算法 在延迟可控的情况下尽可能提高吞吐量JDK9默认
ZGC 并行 用户线程和垃圾回收线程同时执行 整堆 分页算法 STW的时间不超过1ms,且不会随着堆的大小增加而增加

常用命令:

-XX:+PrintCommandLineFlags,查看使用的垃圾收集器

-XX:+UseSerialGC,指定使用Serial GC处理新生代,并且默认会使用Serial Old GC处理老年代

-XX:+UseParNewGC,指定新生代使用ParNew GC,-XX:+UseConcMarkSweepGC,指定老年代使用CMS GC

-XX:+UseParallelGC,指定新生代使用Parallel GC,-XX:+UserParallelOldGC,指定老年代使用Parallel Old GC,这两个配置一个,另一个自动激活

1. Serial GC、Serial Old GC

Serial GC和Serial Old GC是比较早的垃圾回收器,那个时候一般的服务器CPU还只有一核,所以一个线程进行垃圾回收就够了。串行的意思就是两个垃圾回收器不能同时执行。

2. Parallel GC、Parallel Old GC

Parallel GC进行垃圾回收时也会暂停用户线程(STW),与Serial GC的不同就是它时多线程进行垃圾回收的。下面画个图方便理解垃圾回收过程。

在一次垃圾回收过程中,会进行一次STW,并且会有多个线程同时进行垃圾回收,回收完后用户线程回复运行。

3. CMS GC

CMS全称是ConcMarkSweep,即并发标记清除。但是它不是某个JDK默认的,要使用的话就加上-XX:+UseConcMarkSweepGC参数。

CMS GC是Java9之前我们很常用的垃圾回收器,是针对老年代的使用标记-清除算法的垃圾回收器。我们一般会使用CMS GC替代默认的老年代垃圾回收器,因为CMS GC的特点是低暂停。实现低暂停的方法是在初始标记阶段只标记GC Roots直接可达的对象,这个阶段比较短,所以对用户线程来说是低暂停。

下面用一张图展示它的垃圾回收过程:

阶段一,初始标记:

  • STW,暂停所有用户线程。
  • 然后标记GC Roots直接可达的对象,就是第一层对象。
  • 一旦标记完就恢复用户线程继续执行。
  • 这个阶段很快。

阶段二,并发标记:

  • 从上一个阶段标记出的对象,开始遍历整个老年代,标记出所有的可达对象。
  • 耗时虽然比较长,但好在不需要STW,可与用户线程一起执行。
  • 采用的是三色标记算法(大家自行拓展)。

阶段三,重新标记:

  • 由于在并发标记阶段,应用程序线程也在运行,可能会导致一些对象的状态发生变化,例如新的对象被创建或旧的对象被删除。
  • 为了修正这些问题,需要进行一次短暂的停顿,重新检查并更新标记状态
  • 这个阶段也是“Stop-The-World”的,但也不会太长。

阶段四,并发清理:

  • 清除垃圾对象,释放空间供后续分配使用。
  • 清理工作与应用程序线程并发进行,不会引起停顿。

阶段五,并发重置:

  • CMS收集器会准备下一次垃圾回收循环,重置内部数据结构等。
  • 这一阶段也是与应用程序并发进行的。

CMS整个垃圾回收过程更长了,但是STW的时间变短了,而且在垃圾回收过程中大部分时间用户线程可以执行,所以用户体验更好了。

在并发清理过程中,可能用户线程会产生新的垃圾,这些就是“浮动垃圾”,只能等到下一次GC时来清理。

如果在并发标记、并发清理过程中,用户线程产生的新对象要进入老年代,但是老年代空间又不够,那么就会导致“concurrent mode failure”,此时就会利用Serial Old来做一次垃圾回收,就会做一次全局STW。

由于采用的是标记-清除算法,所以会产生内存碎片,可以通过参数 -XX:+UseCMSCompactAtFullCollection 让JVM在执行完标记-清除后再做一次整理,也可以通过 -XX:CMSFullGCsBeforeCompaction 来指定多少次GC后来做整理,默认是0,表示每次GC后都整理。

CMS垃圾回收器能够在大多数时间内与应用程序并发执行,减少了因垃圾回收引起的停顿时间。然而,CMS也有一些缺点,比如它可能产生大量的浮动垃圾(floating garbage),并且在某些情况下仍然会导致较长的停顿。随着Java版本的发展,G1 GC和ZGC等更先进的垃圾回收器逐渐取代了CMS的地位。

4. G1(Garbage-First)

G1垃圾回收器是在 Java 7 update4 之后引入,并在Java 9中成为默认的垃圾收集器的。G1的设计目标是提供高吞吐量的同时,实现可预测的暂停时间,特别适合处理大堆内存的应用场景。下面介绍一些G1垃圾回收器的内存结构。

先看张图:

之前我们讲的垃圾回收器把堆内存分为Eden、S0、S1、老年代这四个区域,每个区域都是连续的。而在G1中,整块堆内存被分成2048个大小相等的region,这些region在物理上不要求是连续的,但在逻辑上是连续的。每个region可以独立地作为Eden、Survivor或老年代的一部分。所以说G1还是把内存分为了Eden、Survivor、老年代区,只不过空间可以是不连续的了。

Humongous区是专门用来存放大对象的(如果一个对象大小超过了一个region的50%,那么就是大对象)

用一张图展示垃圾回收过程:

阶段一,初始标记:

  • 短暂的STW。
  • 标记出直接可达对象。

阶段二,并发标记:

  • 并发遍历整个堆,标记所有可达对象。
  • 不需要STW。
  • 三色标记。

阶段三,最终标记:

  • 这也是一个较短的STW。
  • 修正并发标记期间由于应用程序运行而可能产生的误差。

阶段四,筛选回收:

  • 需要STW,来清除垃圾对象。
  • 可通过 -XX:MaxGCPauseMillis 来指定GC的STW停顿的时间,所以可能并不会回收掉所有的垃圾对象,默认为200ms(略小于人的平均反应速度)。
  • 由于回收时间有限,所有会选择更有回收价值(垃圾更多)的区域进行回收。这也是Garbage-First(垃圾优先)的名字由来。
  • 采用的是复制算法,不会产生碎片(会把某个region里的可达对象移动到空白的region里)。

由于筛选回收阶段的STW时间可能不够用导致垃圾约积越多,为了避免OOM,G1 中还提供了另外三种垃圾回收模式:Young GC、Mixed GC 和 Full GC,它们有各自的触发条件。

Young GC: Eden区满,就会触发G1的YoungGC,对Eden区进行垃圾回收。

Mixed GC: 老年代的占用率达到了 -XX:InitiatingHeapOccupancyPercent 指定的百分比,回收所有的新生代以及部分老年代,以及大对象区。

Full GC: 在进行Mixed GC的过程中,采用的是复制算法,如果没有空的region可用,就会触发Full GC,会STW,并采用单线程来进行标记-整理算法进行GC,相当于一次Serial GC。

标签:标记,回收,STW,线程,垃圾,JVM,GC
From: https://www.cnblogs.com/GilbertDu/p/18542074

相关文章

  • JDK、JRE、JVM之间的区别
     JVM(JavaVirtualMachine,Java虚拟机):-JVM是Java程序的运行平台,它是一种抽象化的计算机,可以将编译后的Java字节码(.class文件)转换为特定操作系统能够执行的机器码。它负责管理内存分配、垃圾回收、线程管理等底层服务,使得Java具有“一次编写,到处运行”的跨平台能力。JRE......
  • JDK、JRE、JVM之间的区别
     JVM(JavaVirtualMachine,Java虚拟机):-JVM是Java程序的运行平台,它是一种抽象化的计算机,可以将编译后的Java字节码(.class文件)转换为特定操作系统能够执行的机器码。它负责管理内存分配、垃圾回收、线程管理等底层服务,使得Java具有“一次编写,到处运行”的跨平台能力。JRE......
  • JVM 参数配置入门与优化案例
    文章目录JVM参数配置入门与优化案例基础内存参数配置堆内存(HeapMemory)元空间(Metaspace)新生代与老年代比例直接内存(DirectMemory)垃圾回收器(GC)设置OOM异常分析设置GC日志设置实战配置案例:Netty服务配置总结与优化建议JVM参数配置入门与优化案例在Java应用的......
  • P11217 【MX-S4-T1】「yyOI R2」youyou 的垃圾桶
    P11217【MX-S4-T1】「yyOIR2」youyou的垃圾桶-洛谷|计算机科学教育新生态(luogu.com.cn)实际上整理整理没什么难的。主要是考数据结构,完了时间复杂度\(O(n\log^2n)\)的树状数组+二分,比\(O(n\logn)\)的线段树上二分还快,而且线段树还差20ms就爆了,线段树还是得优化......
  • springboot毕设 垃圾识别工具箱 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着社会的不断进步和人民生活水平的提高,音乐艺术教育逐渐成为大众关注的焦点。乐器培训作为音乐艺术教育的重要组成部分,近年来得到了快速发展。然而,......
  • jvm之垃圾收集器
    首先总结下垃圾收集器都有哪些:回收年轻代的垃圾收集器:Serial、ParNew、ParallelScavenge。回收老年代的垃圾收集器:CMS、SerialOld、ParallelOld。同时回收老年代和年轻代的:G1。没有一个收集器可以作用于所有的应用场景,只有具体应用选择具体合适的收集器,正是因为如此才......
  • JVM 进阶:深入理解与高级调优
    在学习了JVM的基础知识后,接下来我们将深入了解JVM的内部工作原理、高级优化方法和性能调优技巧,这些内容将帮助你更好地管理Java应用的性能,尤其是在面对大规模应用和高并发场景时。一、深入了解JVM内存结构JVM内存结构的划分和管理直接关系到Java程序的运行效率,深......
  • 思通数科AI平台在智慧城市地面垃圾分类中的项目案例分享
    一、系统概述在当今的城市环境管理中,垃圾分类与识别已成为推动环保与资源回收的重要手段。然而,传统的人工垃圾分类方法耗时、效率低,且容易出错,严重制约了垃圾处理的精细化与可持续发展。思通数科的AI平台专注于解决这一行业痛点。我们的系统通过深度学习和计算机视觉技术,能够精准......
  • 常用的 jvm 调优的参数都有哪些
    ​  堆内存设置-Xms:设置JVM堆的初始大小。例如:​​-Xms2g​​表示初始堆大小为2GB。-Xmx:设置JVM堆的最大大小。例如:​​-Xmx2g​​表示最大堆大小为2GB。-XX:NewRatio:设置年轻代和老年代的比例。例如:​​-XX:NewRatio=4​​表示年轻代和老年代的比例为1......
  • 常用的 jvm 调优的参数都有哪些
       ​ 堆内存设置-Xms:设置JVM堆的初始大小。例如:​​-Xms2g​​表示初始堆大小为2GB。-Xmx:设置JVM堆的最大大小。例如:​​-Xmx2g​​表示最大堆大小为2GB。-XX:NewRatio:设置年轻代和老年代的比例。例如:​​-XX:NewRatio=4​​表示年轻代和老年代的比......