当前位置:首页 > 文章 > 正文内容

java中的垃圾回收算法与垃圾回收器

廖万里3年前 (2022-10-27)文章72073

常用的垃圾回收算法

标记-清除

标记清除算法是一种非移动式的回收算法,分为标记 清除 2个阶段,简而言之就是先标记出需要回收的对象,标记完成后再回收掉所有标记的内存对象,如下图

java中的垃圾回收算法与垃圾回收器

可见回收后图中被标记的对象被删除回收了,但是碎片化比较严重不连续 对于下次分配大对象的时候由于内存不连续性影响比较大,而且每一次Gc的时候需要执行2个操作 1次标记 1次回收

标记-整理压缩

标记整理压缩算法是一种移动式的算法,由于上面标记清除算法导致内存不连续的问题 标记-整理算法就解决了这个问题。

java中的垃圾回收算法与垃圾回收器

工作原理也是2阶段操作而且更复杂了,首先找出(root)根地址的对象一直寻找标记是否被引用,引用了就标记一下,标记完成后把标记的对象按顺序移动排列在一起并清除掉边界的未标记的对象,这样就没有内存碎片。

缺点

  • 由于标记完成后需要移动对象 移动的过程可能会产生STW

  • 2次+调整指针

复制算法

复制算法更粗暴了,逻辑也很简单 通常直接申明了2块一样大小存储空间,每次只使用其中1块空间,当使用的这块空间不够用的时候就触发回收操作,将存活的对象copy到另一块空间中按顺序存放,可回收的就回收删除掉,这样一来就不会出现内存碎片,但是要多浪费50%的内存空间,主要用于年轻代 比如s0 s1亦是如此。

java中的垃圾回收算法与垃圾回收器

分代回收算法

根据对象的存活周期划分为新生代、老年代。因此可以根据不同年代的特点使用不同的回收算法。分代收集目前是大部分JVM

  • 新生代特点

    在新生代中大量的对象产生 又有大量的对象需要销毁,他们存活时间都比较短。基本上都是回收的时候大部分会被回收掉,只有少量的对象是存活不回收的。

    存活对象少,垃圾对象多这就比较适合使用复制算法,复制算法需要用到2块内存空间 每次只使用其中一块,在jdk8中不只是单纯的划分为s0 s1 二块存储空间,还新增了一块Eden ,s0 s1的默认大小是eden的8/1 这样设计的目的在于每次触发回收的时候把90(eden+其中1个s区)的区域中存活的对象copy到10%的存储中,理论上清除了90%的空间,这样做的好处就是不需要花50%的存储空间,只浪费了10%的空间就实现了这个算法逻辑。

  • 老年代特点

    老年代的特点就是对象存活时间都比较长,大量的存活对象就不适合像新生代一样用复制算法了 因为copy的成本太高,这种就比较适合标记清除算法,或者标记清除整理算法。

    优缺点概述

    算法名称优点缺点
    标记-清除简单位置不联系 碎片化严重 效率低 2次扫描
    标记-压缩整理没有碎片效率低 2次扫描 可能会多次重置指针
    复制算法没有碎片 简单高效浪费空间

垃圾回收器

上面的垃圾算法仅仅只是一个理论上的算法 ,正在实现这些算法的叫垃圾回收器,在工作中具体是怎么回收工作的可以不关心,但是需要了解不同的垃圾回收器是基于哪种算法实现的,有助于出现性能问题的时候有思路去参数调优,而不是盲目的问度娘。各个年轻代 老年代垃圾回收器可组合配对方式如下图所示

java中的垃圾回收算法与垃圾回收器java中的垃圾回收算法与垃圾回收器

serial串行收集器

serial回收器是一个串行单线程回收器,在进行垃圾回收的时候必须暂停用户工作线程,直到回收线程处理完成,每次回收必然会STW。比较适合跑在client端应用

java中的垃圾回收算法与垃圾回收器

ParNew收集器

ParNew回收器是新生代垃圾回收器, 就是serial的多线程版本 其它基本上serial差不多的,在ps回收器没有出来之前parNew+cms是服务器端首选

java中的垃圾回收算法与垃圾回收器

Parallel Scavenge收集器

常说的ps 收集器就算它,ps是一个新生代收集器采用复制算法,多线程并行收集。是jdk8的默认新生代回收器。

看起来和parNew有点一样 反正性能就是比它要强,在应用吞吐量方面更优秀。ps一般是和Parallel Old配合使用

java中的垃圾回收算法与垃圾回收器

Serial Old收集器

Serial Old收集器是Serial的老年代版本,同样它也是单线程收集,基于标记-整理算法,工作原理可以参考serial。

Parallel Old收集器

parallel old收集器是ps的老年代版本 是多线程收集器 基于标记-整理算法 弥补了serial old单线程的不足,工作原理参考ps收集器工作流程图。ps+po是jdk8默认的组合 也是我在项目中实践最多的组合。

CMS收集器

cms从jdk1.4开始引入,算是里程碑GC产品,开启了Java领域并发(注意并发与并行parallel的区别 并发是值回收垃圾的时候和用户线程一起干活,并行是指多个GC线程同时回收 )回收的方案。是一个优秀的老年代垃圾回收器。

cms从名字就能看出来是基于并发的 标记-清除算法实现的回收器,它的回收流程分为 初始标记-并发标记-重新标记-并发清除 4个阶段。

  1. 初始标记 (initial mark)
    只是标记GC Root 根对象 会stw 但是由于只是标记了gc roots 所有很快

  2. 并发标记
    根据第1阶段的结果继续往下标记 这个阶段是并发的 不影响用户线程

  3. 重新标记
    为什么会有重新标记这个阶段?是因为并发标记的时候 由于用户线程还在运行 可能产生了新的垃圾 所以需要在标记一次,当然由于第2阶段标记过一次了,这一次理论上会很快 这个阶段会STW

  4. 并发清除
    清理需要回收的对象 不影响用户线程使用。cms有个开关(-XX:CMSFullGCsBeforeCompaction=0)默认是开启碎片整理,由于cms清理后的空间也是有碎片存在的,所以一次清理就会整理一次碎片。此阶段用户线程同样会产生新的垃圾 目前没有解决清除 网上叫为浮动垃圾

所以cms只有在并发标记和并发清除阶段是不影响用户线程停顿的。初始标记 和 重新标记 也是划分的区域标记的,总体上能跟控制gc停顿时间 提高用户体验,工作原理如下

java中的垃圾回收算法与垃圾回收器

当老年代内存使用到92%(-XX:CMSInitiatingOccupancyFraction=92)之后出触发cms回收一次,如果cms在回收期间中 剩余的内存不够用户工作线程使用了(报异常Concurrent Mode Fail) 那么serial old回收器就成了紧急替补队员立即进行回收一次,当然停顿的时间就更长了。由于cms部分阶段是用户线程和gc线程一起工作,如果启动阈值设置得太高,容易导致用户工作线程不够用触发cmf异常,性能反而降低。

G1收集器

G1垃圾回收器可以同时支持年轻代、老年代,G1并没有在物理分区隔离,上面的提到的垃圾回收器都是物理上进行分区的,G1是由一块一块大小相同的region组成,虽然没有物理上进行分区,但是依然保留了年轻代 老年代的概念。回收流程有点类似cms。也是分为初始标记并发标记最终标记筛选回收 4个阶段。

Region的大小可以通过G1HeapRegionSize参数进行设置,其必须是2的幂,范围允许为1Mb到32Mb。基于堆内存的初始值和最大值的平均数计算分区的尺寸,平均的堆尺寸会分出约2000个Region。分区大小一旦设置,则启动之后不会再变化。region之间采用复制算法,因此不容易产生内存碎片。每个Region都有一个Remembered Set。当对引用进行写操作的时候,G1检查该引用的对象是否在别的region中,是的话,则通过CardTable把相关引用信息存到被引用对象的Remembered Set中。当进行内存回收时,把RememberSet加入到GC Roots根节点的枚举范围。这样就可以保证不全堆扫描也不会有遗漏。 内存结构如下

java中的垃圾回收算法与垃圾回收器

  1. Survivor regions(年轻代-Survivor区)

  2. Old regions(老年代)

  3. Humongous regions(巨型对象区域) 占用了Region容量的50%以上对象 巨型对象比较大 一般在并发标记阶段如果可以回收就直接回收了。

  4. Free resgions(未分配区域,也会叫做可用分区)-上图中空白的区域

G1之所以这里厉害在于它用到了一些数据结构的技巧

TLAB(Thread Local Allocation Buffer)本地线程缓冲区

PLAB(Promotion Local Allocation Buffer) 晋升本地分配缓冲区

Collecion Sets(CSets)待收集集合

Card Table 卡表

Remembered Sets(RSets)已记忆集合

回收流程大致如下

  1. 初始标记

    只是标记GC Roots根对象 会stw

  2. 并发标记

    从上一步标记的GC Roots开始计算可达性分析并标记 这阶段耗时但是是并发的 不影响用户线程使用

  3. 最终标记
    上一步执行的过程中产出的变动再一次计算和标记 会stw 短暂的停顿,JVM将这段时间对象变化记录到Remembered Set Log中,在最终标记阶段把Remembered Set Log合并到Remembered Set中。

  4. 筛选回收
    为什么多了一步筛选再回收,在于G1在收集的时候会优先回收比较有价值的region区域,垃圾对象比较多 存活对象比较少的region就算是有价值的 这样就能有效的提高回收效率。因为优先回收掉有价值的region而不是一下全部把堆中的全部垃圾回收完,所以回收的时间基本上能够把控。这个阶段是并行操作但是会有短暂的STW基本感知不到。

JDK10 之前的G1中的GC只有YoungGC,MixedGC。FullGC处理会交给单线程的Serial Old垃圾收集器。

zgc收集器
Shenandoah


本文链接:https://www.kkkliao.cn/?id=153 转载需授权!

分享到:

版权声明:本文由廖万里的博客发布,如需转载请注明出处。


“java中的垃圾回收算法与垃圾回收器” 的相关文章

工龄38年机关事业单位人员正处级养老金有多少钱?

工龄38年机关事业单位人员正处级养老金有多少钱?

机关事业单位人员,工龄38年,正处级,养老金有多少钱?机关事业单位人员,如果在2024年以前退休,那么是属于退休中人,相比退休老人,养老金计算方式比较特殊,如果退休时,当地还没有理顺养老金待遇,就会领取预发养老金,等以后理顺后,再进行补发。那么对于工龄38年,正处级,养老金可以达到多少呢?应该说,正...

“双11”,如何守住钱袋子?

“双11”,如何守住钱袋子?

“双十一”快到了,“剁手”的大斧已高高举起。购物车收藏83件,有的商品开启定价预售模式小姐姐的化妆品要不少钱呀,也不知比平时便宜多少最近几天,同事们都在热议“双十一”。 今年的“双十一”跟以往相比有新变化,比如,缩短预售时间、扩容购物车、差价一键退,不少平台还从晚上8点开始销售等。自从2009年开始...

开始“反扑”了?中国院士正式宣布,厉害的不只有华为

开始“反扑”了?中国院士正式宣布,厉害的不只有华为

随着中国的这些年的不断发展,中国在各方都取得了很大的成就,现在的中国已经发生了翻天覆地的变化。在生活上。我们进入了电商时代,进入了移动支付时代;在科技上,我们进入了智能互联网时代,即将迎来的是全新的5G时代,还有很多很多中国制造都是值得我们骄傲的。特别值得提及的就是,现在中国制造已经成为了我们的一个...

6G专利申请量比拼:美国占比35.2%,日本占比9.9%,中国排第几?

6G专利申请量比拼:美国占比35.2%,日本占比9.9%,中国排第几?

5G对于现在的人们来说已经不是什么神秘的存在,很多国家通过近些年的研究都已经逐步掌握了5G技术。不过就5G技术发展的成熟度、设备完善程度以及信号铺设范围来说,我国都是当之无愧的世界第一。但是随着科技技术的不断发展,对于6G的技术研发也被提上日程。不少国家都开始攻克6G技术,并取得了各项专利。根据有关...

2022年,微信收款出“新规”,余额会受到影响吗?个体商家要留心

2022年,微信收款出“新规”,余额会受到影响吗?个体商家要留心

当今社会市场经济发展,在近十年内,我们社会的支付方式也发生了翻天覆地的变化,近年来大家尤其是年轻人出门购物基本不带现金,使用微信,支付宝等扫一扫,付款码等功能便可以轻松完成支付,在近几年,我们在买东西时,看到几乎所有商家都将自己的收款码打印出来摆放在收银台,埋有许多配套的扫码工具。在这种支付方式的广...

宇宙中发现比光速更快的速度?事实被澄清,这不过是种错觉

宇宙中发现比光速更快的速度?事实被澄清,这不过是种错觉

有比光速更快的速度吗?来自遥远爆炸星系的伽马射线爆发(如图中所示)发射的光比我们所看到的可见光更强大,但这并不意味着它们的速度更快。2018年,天文学家在研究哈勃太空望远镜图像中的两颗碰撞中子星时注意到了一个奇怪的现象:一股明亮的高能粒子流,以 4~7 倍于光速的速度从合并处喷向地球方向。这似乎有些...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。