2021-04-17垃圾回收器

article/2025/7/1 19:57:10

文章目录

  • 七种典型的垃圾回收器
    • 经典收集器与垃圾分代之间的关系
    • 如何查看默认的垃圾回收器
    • Serial回收器
    • ParNew回收器
    • Parallel Scavenge回收器
    • CMS回收器
    • G1回收器
    • 总结
    • ZGC
    • 垃圾收集器的组合关系

七种典型的垃圾回收器

串行回收器:Serial、Serial Old
并行回收器:ParNew、Parallel Scavenge、Parallel Old
并发回收器:CMS、G1

经典收集器与垃圾分代之间的关系

新生代收集器:Serial、ParNew、Parallel Scavenge
老年代收集器:Serial Old、Parallel Old、CMS
整堆收集器:G1

如何查看默认的垃圾回收器

查看命令行相关参数(包括使用的垃圾收集器):

-XX:+PrintCommandLineFlags

使用命令行指令:

jinfo -flag 相关垃圾收集器参数 进程ID

Serial回收器

串行回收,JDK1.3之前回收新生代唯一的选择。Serial收集器作为HotspotClient模式下的默认新生代垃圾收集器。
该收集器采用复制算法、串行回收和STW机制的方式执行内存回收。
Serial Old也采用了串行回收和STW机制,内存回收算法是标记-压缩算法。是运行在Client模式下的默认的老年代的垃圾回收器。
Serial OldServer模式下主要有两个用途:

  1. 与新生代的Parallel Scavenge配合使用
  2. 作为老年代CMS收集器的后备垃圾收集方案

该收集器是一个单线程收集器,它只会使用一个CPU或一条收集线程去完成垃圾收集工作,并且在他进行垃圾回收的时候,必须暂停其他所有的工作线程,直到它收集结束。
优势:
简单而高效,对于限定单个CPU的环境来说,该收集器由于没有线程交互的开销,专心做垃圾收集自然获得最高的单线程收集效率。
Hotspot中,使用-XX:+UseSerialGC参数可以指定年轻代和老年代都使用串行收集器。

ParNew回收器

并行回收ParNew收集器除了采用并行回收的方式执行内存回收外,与Serial垃圾收集器之间几乎没有任何区别。在年轻代中同样是采用复制算法、STW机制。该垃圾收集器是很多JVM运行在Server模式下新生代的默认垃圾收集器。
对于新生代,回收次数频繁,使用并行方式高效。
对于老年代,回收次数少,使用串行方式节省资源(CPU并行需要切换线程,串行可以省去切换线程的资源)。

Parallel Scavenge回收器

吞吐量优先,该收集器同样也采用了复制算法、并行回收和STW机制
该收集器的目标是达到一个可控制的吞吐量,自适应调节策略也是该收集器与ParNew的一个重要区别。
高吞吐量可以高效率的利用CPU的时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。常见在服务器环境中使用。Parallel在JDK1.6时提供了用于执行老年代垃圾收集的Parallel Old收集器,用来替代Serial Old收集器。Parallel Old采用了标记-压缩算法,是基于并行回收和STW机制
在Java8中,默认是此垃圾收集器。
自适应调节策略:

  1. 在这种模式下,年轻代的大小、EdenSurvivor的比例、晋升老年代的对象年龄等参数会被自动调整,已达到在堆大小、吞吐量和停顿时间之间的平衡点。
  2. 在手动调优比较困难的场合,可以直接使用这种自适应的方式,仅指定虚拟机的最大堆、目标吞吐量和停顿时间,让虚拟机自己完成调优工作。

CMS回收器

低延迟,JDK1.5时期,Hotspot推出了一款适合在强交互应用中使用的垃圾收集器,是一款真正意义上的并发收集器,第一次实现了让垃圾收集线程与用户线程同时工作。
CMS收集器的关注点是尽可能缩短垃圾收集时用户线程的停顿时间。该收集器采用标记-清除算法,STW机制
CMS作为老年代的收集器,无法与新生代收集器Parallel Scavenge(底层框架不同)配合工作,所以在JDK1.5中使用CMS作为老年代收集器的时候,新生代只能选择ParNewSerial收集器中的一个。
CMS整个过程分为4个主要阶段:
初始标记阶段、并发标记阶段、重新标记阶段和并发清除阶段。
3. 初始标记阶段:在这个阶段中,程序中所有工作线程都将会因为STW机制而出现短暂的暂停,这个阶段的主要任务是仅仅标记出GC Roots能直接关联到的对象。一旦标记结束之后就会恢复之前被暂停的所有应用线程,由于直接关联的对象比较小,所以这里速度非常快。
4. 并发标记阶段:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要暂停用户线程,可以与垃圾收集线程一起并发运行。
5. 重新标记阶段:由于在并发标记阶段中,程序的工作线程会和垃圾收集线程同时运行或者交叉运行,因此为了修正并发标记期间,因用户线程继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间通常会比初始标记阶段稍长一些,但也远比并发标记阶段的时间短。(STW)
6. 并发清除阶段:此阶段清理删除掉标记阶段判断的已经死亡的对象,释放内存空间,由于不需要移动存活对象,所以这个阶段也是可以和用户线程同时并发的。(存在碎片问题)。

CMS优点:

  • 并发收集
  • 低延迟

CMS缺点:

  • 会产生内存碎片
  • CMS收集器对CPU资源非常的敏感
  • CMS收集器无法处理浮动垃圾

G1回收器

区域分代化。是JDK9以后的默认垃圾回收器。G1的设定目标是在延迟可控的情况下获得尽可能高的吞吐量。G1是一个并行回收器,他把堆内存分割为很多不相关的区域(物理上不连续),使用不同的区域来表示Enden、幸存者0区、幸存者1区、老年代等。
该收集器有计划的避免在整个Java堆上进行全区域的垃圾收集,G1跟踪各个区域里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的区域。
G1是一款面向服务端应用的垃圾收集器,主要针对配备多核CPU及大容量内存的机器,以极高概率满足GC停顿时间的同时,还兼具高吞吐量的性能特征。
优势:

  • 并行与并发
    并行性:G1在回收期间,可以有多个GC线程同时工作,有效利用多核计算能力。此时用户线程STW.
    并发性:G1拥有与应用程序交替执行的能力,部分工作可以和应用程序同时执行,因此,一般来说,不会在整个回收阶段发生完全阻塞应用程序的情况。

  • 分代收集
    它区分老年代和年轻代,它同时兼顾老年代和年轻代

  • 空间整合
    内存的回收是以Region为单位的,Region之间是复制算法,但整体上实际可看做是标记-压缩算法,这两种算法都可以避免内存碎片。这话特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。

  • 可预测的停顿时间模型(软实时)
    由于分区的原因,G1可以值选取部分区域进行内存回收,这样缩小了回收的范围,因此对于全局停顿情况的发生也能得到较好的控制。

缺点:

  • 相较于CMS,G1无论是为了垃圾收集产生的内存占用还是程序运行时的额外执行负载都要比CMS要高。(需占用额外的内存空间)
  • 在小内存应用上CMS的表现大概率优于G1,G1在大内存应用上发挥其优势。
    G1垃圾收集器还增加了一个新的内存区域,叫Humongous内存区域,主要用于存储大对象,如果超过了1.5个region区域,就放到H区。
    设置H区的原因:
    对于堆中的大对象,默认直接被分配到老年代,但是如果他是一个短期存在的大对象,就会对垃圾收集器造成负面影响(内存泄露),为了解决这个问题,G1划分了一个Humongous区,它用来专门存放大对象。如果一个H区装不下一个大对象,那么G1会寻找连续的H区来存储,为了能找到连续的H区,有时候不得不启动Full GC。G1的大多数行为都把H区作为老年代的一部分来看待。
    G1垃圾回收器的回收过程:
    应用程序分配内存,当年轻代的Eden区用尽时开始年轻代的回收过程:G1的年轻代收集阶段是一个并行的独占式收集器。在年轻代回收期,G1 GC暂停所有应用程序的线程,启动多线程执行年轻代的回收。然后从年轻代区间移动存活对象到Survivor区间或者老年区间,也有可能是两个区间都会涉及。
    当堆内存使用达到一定值(默认为45%)时,开始老年代并发标记过程。
    标记完成马上开始混合回收过程。对于一个混合回收期,G1 GC从老年区间移动存活对象到空闲区域,这些空闲区域也就成为了老年代的一部分。和年轻代不同,老年代的G1回收器和其他GC不同,G1的老年代回收器不需要整个老年代被回收,一次只需要扫描/回收一小部分老年代的Region就可以了,同时,这个老年代Region和年轻代一起被回收。
  1. 年轻代GC:
    JVM启动时,G1先准备好Eden区,程序在运行过程中不断创建对象到Eden区,当Eden空间耗尽时,G1会启动一次年轻代垃圾回收过程。年轻代垃圾回收只会回收EdenSurvivor区。YGC时,首先G1停止应用程序的执行,G1创建回收集,回收集是指需要被回收的内存分段的集合,年轻代回收过程的回收集包括年轻代Eden区和Survivor区所有的内存片段。
    具体过程:
    (1)第一阶段:扫描根
    根指的是static变量指向的对象,正在执行的方法调用链条上的局部变量等。根引用连同RSet(记忆集)记录的外部引用作为扫描存活对象的入口。
    (2)第二阶段:更新RSet
    处理dirty card queue中的card,更新RSet。此阶段完成后,RSet可以准确的反应老年代对所在的内存分段中的对象的引用。
    (3)第三阶段:处理RSet
    识别被老年代对象指向的Eden区中的对象,这些被指向的Eden中的对象被认为是存活的对象。
    (4)第四阶段:复制对象
    此阶段,对象树被遍历,Eden区内存段中存活的对象会被复制到Survivor区中空的内存分段,Survivor区内存段中存活的对象如果年龄值未达到阈值,则会加1,达到阈值就会被复制到Old区空的内存分段。如果Survivor区空间不够,Eden空间的部分数据会直接晋升到老年代的空间。
    (5)第五阶段:处理引用
    处理Soft、Weak、Phantom、Final、JNI Weak等引用。最终Eden区空间的数据为空,GC停止工作,而目标内存中的对象都是连续存储的,没有碎片,所以复制过程可以达到内存整理的效果,减少碎片。
  2. 老年代并发标记过程
    (1)初始阶段标记
    标记从根节点直接可达的对象。这个阶段是STW的,并且会触发一次年轻代的GC。
    (2)根区域扫描
    G1 GC扫描Survivor区中直接可达的老年代区域对象,并标记被引用的对象。这一过程必须在young GC之前完成。
    (3)并发标记
    在整个堆中进行并发标记(和应用程序并发执行),此过程可能被young GC中断。在并发标记阶段,若发现区域对象中的所有对象都是垃圾,那这个区域会被立即回收。同时,并发标记过程中,会计算每个区域的对象活性(区域中存活对象的比例)。
    (4)再次标记
    由于应用程序持续进行,需要修正上一次的标记结果。是STW的。G1中采用了比CMS更快的初始快照算法:snapshot-at-the-beginning(STAB)
    (5)独占清理
    计算各个区域的存活对象和GC回收比例,并进行排序,识别可以混合回收的区域,为下阶段做铺垫,是STW的。这个阶段实际上不会去做垃圾的收集。
    (6)并发清理阶段
    是被并清理完全空闲的区域。
  3. 混合回收
    当越来越多的对象晋升到老年代Old region时,为了避免堆内存被耗尽,虚拟机会触发一个混合的垃圾收集器,即Mixed GC,除了回收整个Young Region,还会回收一部分的Old Region,这里需要注意,是部分老年代,而不是整个老年代。可以选择哪些Old Region进行回收,从而可以对垃圾回收的耗时时间进行控制,也要注意的是Mixed GC并不是Full GC
    (1)并发标记结束之后,老年代中百分百为垃圾的内存分段被回收了,部分为垃圾的内存分段被计算了出来。默认情况下,这些老年代的内存分段会分8次被回收。
    (2)混合回收的回收集包括八分之一的老年代内存分段,Eden区内存分段,Survivor区内存分段。混合回收的算法和年轻代回收的算法完全一样,只是回收集多了老年代的内存分段。
    (3)由于老年代中的内存分段默认分8次回收,G1会优先回收垃圾多的内存分段。垃圾占内存分段的比例越高,越先被回收。并且有一个阈值会决定内存分段是否被回收。如果垃圾占比太低,意味着存活的对象占比高,在复制的时候会花费更多的时间。
    (4)混合回收并不一定进行8次,可以设置阈值-XX:G1HeapWastePercent,默认值为10%。
  4. 如果需要,单线程、独占式、高强度的Full GC还是继续存在的,他针对GC的评估失败提供了一种失败的保护机制,即强力回收。导致full GC的原因有两个:
    (1)Evacuation的时候没有足够的to-space来存放晋升的对象
    (2)并发处理过程完成之前空间耗尽。

总结

垃圾收集器分类作用位置使用算法特点适用场景
Serial串行运行新生代复制算法响应速度优先适用于单CPU环境下的client场景
ParNew并行运行新生代复制算法响应速度优先多CPU环境Server模式下与CMS配合使用
Parallel并行运行新生代复制算法吞吐量优先适用于后台运算而不需要太多交互的场景
Serial Old串行运行老年代标记-压缩算法响应速度优先适用于单CPU环境下的client场景
Parallel Old并行运行老年代标记-压缩算法吞吐量优先适用于后台运算而不需要太多交互的场景
CMS并发运行老年代标记-清除算法响应速度优先适用于互联网或B/S业务
G1并发、并行运行新生代、老年代标记-压缩、复制算法响应速度优先面向服务端应用

ZGC

在尽可能对吞吐量影响不大的情况下,实现在任意堆内存大小都可以把垃圾收集的停顿时间限制在十毫秒以内的低延迟。
ZGC收集器是一款基于Region内存布局的,不设分代的,使用了读屏障、染色体指针和内存多重映射等技术来实现的可并发的标记-压缩算法,以低延迟为首要目标的一款垃圾收集器。
工作过程分为四个阶段:
并发标记->并发预备重分配->并发重分配->并发重映射等。
ZGC几乎在所有的地方并发执行,除了初始标记的STW。

垃圾收集器的组合关系

在这里插入图片描述
说明:

  1. 其中Serial Old作为CMS出现“Concurrent Mode Failure”失败后的后备预案。
  2. 橘色虚线表示由于维护和兼容性测试的成本,在JDK 8时将Serial+CMS、ParNew+Serial Old这两个组合声明为废弃,并在JDK 9中完全取消了对这些组合的支持。
  3. 绿色虚线表示JDK14中,弃用Parallel ScavengeSerialOld GC的组合。
  4. JDK14中,删除了CMS垃圾回收器。

http://chatgpt.dhexx.cn/article/5tfJVeYR.shtml

相关文章

常见的垃圾回收器

一、参考文章 https://www.cnblogs.com/datiangou/p/10245874.html https://www.cnblogs.com/jason1990/archive/2019/10/24/11732261.html 二、常用垃圾回收器 1. JDK诞生 Serial追随 提高效率,诞生了PS,为了配合CMS,诞生了PN&#xff0c…

Hack The Box——Luanne

目录 简介 信息收集 漏洞发现 Lua代码注入 漏洞利用 权限提升 用户r.michaels的Shell 总结 简介 靶机偏CTF类型,评分才2.3,评分这么低是有原因的。总体思路是通过lua代码注入获得WebShell,然后利用CVE-2010-2320读取普通用户ssh私钥…

I Box

Box 链接:https://ac.nowcoder.com/acm/contest/7854/I 来源:牛客网 Bella is working in a factory that produces boxes. All boxes are in a shape of rectangular parallelepipeds. A net of the corresponding parallelepiped is cut out of a …

常用的垃圾回收器

1、常见的垃圾回收器介绍: 如果说收集算法是内存回收的⽅法论,那么垃圾收集器就是内存回收的具体实现。现在为⽌还没有最好的垃圾收集器出现,更加没有万能的垃圾收集器,我们能做的就是根据具体应⽤场景选择适合⾃⼰的垃圾收集器。…

Java 捡垃圾利器

文章目录 垃圾收集器Serial优点使用场景 ParNew使用场景配合使用CMSG1 Parallel Scavenge使用场景参数 Serial OldParallel OldCMS流程优点缺点 G1概述主要特征内存分布回收定位问题与解决方案与 CMS 小结拓展阅读参考资料 垃圾收集器 收集算法是内存回收的方法论,…

垃圾回收站

【冒泡排序】c实现冒泡排序代码 【冒泡排序】c实现冒泡排序代码 【冒泡排序】c实现冒泡排序代码固态激光雷达 转载自 yangchuang93 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 冒泡排序的基…

labweek8

实验报告 实验内容 进程间通信—消息机制。 (1) 编译运行课件 Lecture 09 例程代码:Algorithms 9-1 ~ 9-2. (2) 修改代码,观察在 msgsnd 和 msgrcv 并发执行情况下消息队列的变化情况。 (3) 仿照 alg.8-4~8-6,编制基于 POSIX API 的进程间…

常见垃圾回收器

CMS和G1是最重要的 新生代一般采用标记复制,老年代一般采用标记整理算法 Serial:垃圾回收线程只有一个,而且垃圾回收线程工作的时候其他用户线程要停下来 Parnew:Serial的多线程版本,有多个垃圾回收线程,垃…

垃圾回收(一)

文章目录 1. 确定哪些对象还“存活”,哪些已经“死去”1.1 引用计数算法1.2 可达性分析算法1.3 引用 2.垃圾回收算法2.1 分代收集理论跨代引用 2.2 标记-清除算法2.3 标记-复制法2.4 标记-整理算法 垃圾收集需要完成的三件事: 哪些内存需要回收&#xff…

python 垃圾箱-垃圾回收

前戏 解释器在执行到定义变量的语法时,会申请内存空间来存放变量的值,而内存的容量是有限的,这就涉及到变量值所占用内存空间的回收问题,当一个变量值没有用了(简称垃圾)就应该将其占用的内存给回收掉,那什么样的变量值…

纪念第一届cccc天梯赛

来一篇迟到的文章 先来爆一下战绩吧:SDUT,学校排名全国第六获金,山东省冠军。学校一共三支队伍,学长们一支最强的队获一等奖,剩下的两支二等奖。 战绩总体来看还不错吧,离不开我们每一个队员和老师们的努…

2021 CCCC天梯赛补题

前言不想看请直接跳过~~~~ 前言检讨:天梯赛我拉垮了,我拖了队伍后腿,我有罪。 分析原因,首先是前一个星期训练量不够,没有跟上队友训练的进度,一些基础的STL的…

2021年CCCC天梯赛 【部分题题解】

天梯赛有三个level,第一个level基本就是语法题,第二个level是基础算法和STL库的一些应用。 第三个level就是一些难的算法。 L3的题都不是太会,有思路但是写不出来。 目录 L1人与神两小时学完C语言强迫症降价提醒机器人大笨钟的心情吉老师的回…

2021年CCCC天梯赛L3 还原文件题解

题目如下 一份重要文件被撕成两半,其中一半还被送进了碎纸机。 我们将碎纸机里找到的纸条进行编号,如图 1 所示。然后根据断口的折线形状跟没有切碎的半张纸进行匹配,最后还原成图 2 的样子。 要求你输出还原后纸条的正确拼接顺序。 图 1…

2020CCCC天梯赛补题记录

目录 总结补题L2-035 完全二叉树的层序遍历 (25分)L2-036 网红点打卡攻略 (25分)L3-025 那就别担心了 (30分)28分版本:30分版本(记忆化搜索) 总结 1.口罩那题打完就只剩三十分钟了,之后卡在了完全二叉树的层序遍历那题,就没有再敢往后看&…

2021 CCCC天梯赛L1补题

前言 这次天梯赛表现没有达到预期,L1的分没有拿全,L2有2题没考虑完全,总之很愧疚拖了队友后腿。今天先补上L1没拿满分的题。 L1补题 前言L1-078 吉老师的回归输入样例1输出样例1输入样例2输出样例2 思路代码实现 L1-080 乘法口诀数列输入样例…

CCCC天梯赛 L2-037 包装机

CCCC天梯赛 L2-037 包装机 一种自动包装机的结构如图 1 所示。 首先机器中有 N 条轨道,放置了一些物品。 轨道下面有一个筐。 当某条轨道的按钮被按下时,活塞向左推动,将轨道尽头的一件物品推落筐中。 当 0 号按钮被按下时,机械手…

2022年CCCC天梯赛题解

L1-1今天我要赢 原题链接 代码 #include<bits/stdc.h> #define int long long #define rep(i, a, b) for(int ia;i<b;i) #define Rep(i, a, b) for(int ia;i>b;--i) using namespace std; const int N 10005; inline int read(){int s0,w1;char chgetchar();wh…

第八届cccc团体程序设计天梯赛——个人参赛总结——无代码纯粹的参赛总结

第八届cccc团体程序设计天梯赛——个人参赛总结——无代码纯粹的参赛总结 目录 第八届cccc团体程序设计天梯赛——个人参赛总结——无代码纯粹的参赛总结引言~介绍一下cccc天梯赛&#xff08;选读&#xff09;开篇介绍&#xff08;以下是个人经历部分的分享&#xff09;赛前准备…

怎样合理地营销推广App和吸引住大量的客户提高转化?

开发App进行后&#xff0c;一切应用软件都必须营销推广&#xff0c;尤其是在互联网技术收益消退的情况下&#xff0c;怎样合理地营销推广和吸引住大量的客户总流量早已变成很多互联网公司最关注的难题。 APP运用引流方法工作中看上去很繁杂&#xff0c;难度系数很大&#xff0…