JVM-垃圾回收

目录

1、GC过程

2、垃圾回收算法

2.1、标记-清除

2.2、标记-整理

2.3、复制

2.4、分代收集算法

3、TLAB

4、对象如何进入老年代

5、卡片标记

6、HotSpot垃圾回收器

6.1、年轻代垃圾回收器

6.2、老年代垃圾回收器

6.3、如何配置垃圾回收器

6.4、STW

7、CMS垃圾回收器

7.1、定义

7.2、设计目标

7.3、CMS回收过程

7.4、内存碎片

7.5、CMS的停顿(STW)

7.6、CMS缺点

8、G1垃圾回收器

8.1、为什么需要G1?

8.2、G1的设计目标

8.3、CMS和G1的区别?

8.4、G1 有年轻代和老年代的区分吗?

8.5、G1的优点

8.6、G1的数据结构

8.8、G1的垃圾回收过程

8.8.1、年轻代回收(STW)

8.8.2、并发标记

8.8.3、混合回收(Mixed GC)

9、ZGC


1、GC过程

        先找到活跃的对象,然后把其他不活跃的对象判定为垃圾,然后删除。所以垃圾回收只与活跃的对象有关,和堆的大小无关。

2、垃圾回收算法

2.1、标记-清除

        标记存活的对象,然后将未标记的对象统一清除。缺点是会产生内存碎片。

2.2、标记-整理

        标记存活的对象,然后把整个堆中未标记的对象压缩到堆的其中一块,从而避免了内存的碎片化问题。

2.3、复制

        将内存一分为二,每次只使用其中一半,满了之后将存活的对象复制到另一半内存中,然后将剩下的碎片一次性擦除。缺点是需要两倍的内存空间。

2.4、分代收集算法

  • 新生代:复制。(新生代存活对象少,复制代价小)
  • 老年代:标记清除,标记整理

年轻代 = 1*Eden + 2*survivor

当年轻代中的 Eden 区分配满的时候,就会触发年轻代的 GC(Minor GC)。具体过程如下:
1、在 Eden 区执行了第一次 GC 之后,存活的对象会被移动到其中一个 Survivor 分区(以下简称from);
2、Eden 区再次 GC,这时会采用复制算法,将 Eden 和 from 区一起清理。存活的对象会被复制到 to 区;接下来,只需要清空 from 区就可以了。

所以在这个过程中,总会有一个 Survivor 分区是空置的。Eden、from、to 的默认比例是 8:1:1,所以只会造成 10% 的空间浪费。( -XX:SurvivorRatio 进行配置的(默认为 8))

3、TLAB

        Thread Local Allocation Buffer,JVM 默认给每个线程开辟一个 buffer 区域,用来加速对象分配。这个 buffer 就放在 Eden 区中。

        对象的分配优先在 TLAB上 分配,但 TLAB 通常都很小,所以对象相对比较大的时候,会在 Eden 区的共享区域进行分配。

4、对象如何进入老年代

  • 提升

        对象在新生代的GC存活次数阈值:‐XX:+MaxTenuringThreshold(最大为15)。即一个对象,在15次GC后,依然存活,那么将该对象提升到老年代。

  • 分配担保

        当 Survivor 空间不够,就需要依赖其他内存(指老年代)进行分配担保。这个时候,对象也会直接在老年代上分配。

  • 大对象直接分配到老年代
  • 动态对象年龄判断

        比如,如果幸存区中相同年龄对象大小的和,大于幸存区的一半,大于或等于 age 的对象将会直接进入老年代。

5、卡片标记

        老年代是被分成众多的卡页(card page)的(一般数量是 2 的次幂)。

        卡表(Card Table)就是用于标记卡页状态的一个集合,每个卡表项对应一个卡页。

        如果年轻代有对象分配,而且老年代有对象指向这个新对象, 那么这个老年代对象所对应内存的卡页,就会标识为 dirty,卡表只需要非常小的存储空间就可以保留这些状态。

        垃圾回收时,就可以先读这个卡表,进行快速判断。

6、HotSpot垃圾回收器

6.1、年轻代垃圾回收器

  • Serial:单线程,垃圾回收时暂停用户线程,复制算法。
  • ParNew:多线程,垃圾回收时暂停用户线程。追求降低用户停顿时间,适合交互式应用。强交互弱计算。
  • Parallel Scavenge:多线程垃圾回收器,追求 CPU 吞吐量,能够在较短时间内完成指定任务,适合没有交互的后台计算。弱交互强计算。

6.2、老年代垃圾回收器

  • Serial Old:单线程,垃圾回收时暂停用户线程,标记-整理算法。
  • Parallel Old:Parallel Scavenge 的老年代版本,追求 CPU 吞吐量。
  • CMS:垃圾回收和用户线程并发执行。以获取最短 GC 停顿时间为目标的收集器,它在垃圾收集时使得用户线程和 GC 线程能够并发执行,因此在垃圾收集过程中用户也不会感到明显的卡顿。

6.3、如何配置垃圾回收器

  • -XX:+UseSerialGC 年轻代和老年代都用串行收集器
  • -XX:+UseParNewGC 年轻代使用 ParNew,老年代使用 Serial Old
  • -XX:+UseParallelGC 年轻代使用 ParallerGC,老年代使用 Serial Old
  • -XX:+UseParallelOldGC 新生代和老年代都使用并行收集器
  • -XX:+UseConcMarkSweepGC,表示年轻代使用 ParNew,老年代的用 CMS
  • -XX:+UseG1GC 使用 G1垃圾回收器
  • -XX:+UseZGC 使用 ZGC 垃圾回收器

6.4、STW

        Stop the world,在垃圾回收时,暂停用户的一切线程。垃圾回收器是为了让GC时间更短,减少停顿,并不能完全消除停顿。

7、CMS垃圾回收器

7.1、定义

  • 并发标记清除垃圾收集器
  • 年轻代:复制算法
  • 老年代:并发标记-清除算法

7.2、设计目标

  • 避免在老年代 GC 时出现长时间的卡顿。
  • 它把最耗时的一些操作,做成了和应用线程并行。

7.3、CMS回收过程

初始标记(STW状态:(时间短))
        1、标记直接关联GC ROOT的对象;
        2、标记年轻代中对象的引用。

并发标记(并行)
        1、标记所有可达的对象,耗时长,但可与用户线程并行执行。
        2、将老年代中发生变化的卡页,标记为dirty状态。

并发预清理(并行)
        1、重新标记老年代中状态为dirty的卡页,并清除掉dirty的状态;
        2、将老年代中发生变化的卡页,标记为dirty状态。

并发可取消的预清理(可选)(并行)
        在满足某些条件的时候,可以终止,比如迭代次数、有用工作量、消耗的系统时间等。

最终标记(SWT)
        完成老年代中所有存活对象的标记。(处理老年代中的所有状态为dirty的卡页,且不会再增加新的dirty状态的卡页)

并发清除(并发)
        删除不可达对象,并回收空间。(新产生的垃圾对象留待下次GC处理,被称作浮动垃圾)

并发重置(并发)
        重置 CMS 算法相关的内部数据,为下一次 GC 循环做准备。

7.4、内存碎片

一般情况下,当老年代的使用率达到 70%,就会触发 GC。
可通过参数 -XX:CMSInitiatingOccupancyFraction 用来配置这个比例。

CMS 对老年代回收时,并没有内存的整理阶段。所以,CMS提供了两个参数来解决这个问题:

  • UseCMSCompactAtFullCollection(默认开启):表示在要进行 Full GC 的时候,进行内存碎片整理。内存整理的过程是无法并发的,所以停顿时间会变长。
  • CMSFullGCsBeforeCompaction:每隔多少次不压缩的 Full GC 后,执行一次带压缩的 Full GC。默认值为 0,表示每次进入 Full GC 时都进行碎片整理。

7.5、CMS的停顿(STW)

  1. 初始标记,这部分的停顿时间较短;
  2. Minor GC(可选),在预处理阶段对年轻代的回收,停顿由年轻代决定;
  3. 重新标记,由于 preclaen 阶段的介入,这部分停顿也较短;
  4. Serial-Old 收集老年代的停顿,主要发生在预留空间不足的情况下,时间会持续很长;
  5. Full GC,永久代空间耗尽时的操作,由于会有整理阶段,持续时间较长。

7.6、CMS缺点

  1. CPU敏感:并发标记、清除过程中因占用一部分线程可能导致应用程序变慢。
  2. 并发清除过程中会产生浮动垃圾。
  3. 标记清除算法会存在空间碎片的情况。

8、G1垃圾回收器

8.1、为什么需要G1?

        CMS在发生 Minor GC 时,由于 Survivor 区已经放不下了,多出的对象只能提升(promotion)到老年代。但是此时老年代因为空间碎片的缘故,会发生 concurrent mode failure 的错误。这个时候,就需要降级为 Serail Old 垃圾回收器进行收集。

8.2、G1的设计目标

        分而治之,部分收集。

        在任意 1 秒的时间内,停顿不得超过 10ms。-XX:MaxGCPauseMillis=10。(控制STW时间)

8.3、CMS和G1的区别?

  • CMS回收器,是对某个年代的整体收集,无法控制收集时间;
  • G1回收器,把堆分成了很多份,把每一份当做一个小目标,控制收集时间。

8.4、G1 有年轻代和老年代的区分吗?

G1堆内存划分
  • G1也会分年轻代和老年代,只不过它们在内存上是不连续的,而是由一小份一小份(Region)组成,被称作小堆区。
  • 对象超过Region大小的50%,会被分配到黄色区域,被称作Humongous Region(连续的小堆区)。
  • 可通过-XX:G1HeapRegionSize=<N>M设置Region大小。
  • 垃圾回收的时候,会优先回收垃圾最多的小堆区。

8.5、G1的优点

  • 任意1秒内停顿时间不会超过10ms;
  • 停顿时间不会随着堆的增大而增大;
  • 复制算法和标记整理算法,保证无空间碎片问题。

8.6、G1的数据结构

Rset

  • 用于记录和维护Region之间的对象引用关系。
  • 把 RSet 理解成一个 Hash,key 是引用的 Region 地址,value 是引用它的对象的卡页集合。
  • 年轻代的Rset:只保存来自老年代的引用,因为年轻代的回收是针对所有年轻代Region;
  • 老年代的Rset:只保存老年代对它的引用,因为老年代回收之前,会先对年轻代进行垃圾回收。

CSet

        收集集合,保存一次GC中将执行垃圾回收的区间(Region)。

8.8、G1的垃圾回收过程

8.8.1、年轻代回收(STW)

Minor GC,Eden区满的时候,会发生年轻代的垃圾回收。
跨代引用使用 RSet 数据结构来追溯,会一次性回收掉年轻代的所有 Region。

  1. 扫描根:根,可以看作是我们前面介绍的 GC Roots,加上 RSet 记录的其他 Region 的外部引用。
  2. 更新RSet:RSet 可以准确的反映老年代对所在的内存分段中对象的引用。
  3. 处理RSet:识别被老年代对象指向的 Eden 中的对象,这些被指向的 Eden 中的对象被认为是存活的对象。
  4. 复制对象:Eden 区内存段中存活的对象会被复制到 Survivor 区中空的 Region。
  5. 处理引用:处理 Soft、Weak、Phantom、Final、JNI Weak 等引用。结束收集。

8.8.2、并发标记

当整个堆内存使用达到一定比例(默认是 45%),并发标记阶段就会被启动。
可通过参数 -XX:InitiatingHeapOccupancyPercent 进行配置。

  1. 初始标记(STW):GC ROOT扫描
  2. Root 区扫描:扫描对老年代的引用,并标记被引用的对象。
  3. 并发标记:从 GC Roots 开始对 heap 中的对象标记,标记线程与应用程序线程并行执行,并且收集各个 Region 的存活对象信息。
  4. 重新标记(STW):标记那些在并发标记阶段发生变化的对象。
  5. 清理阶段:如果发现 Region 里全是垃圾,在这个阶段会立马被清除掉。不全是垃圾的 Region,并不会被立马处理,它会在 Mixed GC 阶段,进行收集。

8.8.3、混合回收(Mixed GC)

        在 Minor GC 之后,如果判断这个占比达到了某个阈值(垃圾占比),下次就会触发 Mixed GC。这个阈值,由 -XX:G1HeapWastePercent 参数进行设置(默认是堆大小的 5%)。

9、ZGC

  • 停顿时间不会超过 10ms;
  • 停顿时间不会随着堆的增大而增大(不管多大的堆都能保持在 10ms 以下);
  • 可支持几百 M,甚至几 T 的堆大小(最大支持 4T)。
  • 连逻辑上的年轻代和老年代也去掉了,只分为一块块的 page,每次进行 GC 时,都会对 page 进行压缩操作,所以没有碎片问题。

以上内容为个人学习理解,如有问题,欢迎在评论区指出。

部分内容截取自网络,如有侵权,联系作者删除。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/125686.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt 继承QAbstractTableModel实现自定义TableModel

1.简介 QAbstractTableModel是Qt框架中的一个抽象类&#xff0c;用于实现数据模型&#xff0c;用于在Qt的视图组件中展示和编辑表格数据。它提供了一些基本的接口和默认实现&#xff0c;可以方便地创建自定义的表格数据模型。 QAbstractTableModel的主要功能包括以下几点&…

吃啥大转盘

经常跟朋友出去吃饭&#xff0c;选择太困难了所以写了个简单的转盘&#xff0c;直接copy到txt文本然后把文件后缀改成html即可。 需要换食物直接在文件中找到 list 值按照格式替换一下即可。 效果&#xff1a; 代码块&#xff1a; <html><head><meta http-…

制作一个用户登录界面

Flask-WTF扩展使用Python类来表示web表单。表单类只是将表单的字段定义为类变量。 再次考虑到分离的问题&#xff0c;我将使用一个新的app/forms.py模块来存储我的web表单类。首先&#xff0c;让我们定义一个用户登录表单&#xff0c;它要求用户输入用户名和密码。表单还将包括…

Window 11中安装Rust编译环境和集成开发环境

https://blog.csdn.net/weixin_43882409/article/details/87616268是我参考的一篇文章。 下载 先到https://www.rust-lang.org/learn/get-started&#xff0c;下载64-Bit&#xff08;64位&#xff09;的rustup-init.exe文件。 使用其他方式进行安装的网址https://forge.rust…

Unity Mirror学习(二) Command属性使用

Command&#xff08;命令&#xff09;属性 1&#xff0c;修饰方法的&#xff0c;当在客户端调用此方法&#xff0c;它将在服务端运行&#xff08;我的理解&#xff1a;客户端命令服务端做某事&#xff1b;或者说&#xff1a;客户端向服务端发消息&#xff0c;消息方法&#xff…

(StateFlow ShareFlow) VS (Flow LiveData)

目录 数据流程 大致流程 切换线程 StateFlow & ShareFlow StateFlow 构建StateFlow &ShareFlow 在之前的Flow&#xff0c;collect函数浅析和仿Flow构建器创建数据流文章中我们探索了flow的简单使用及它的简单原理&#xff0c;但是生产过程中我们往往会借用这些基…

小程序订单中心path设置本次审核不通过,审核原因:小程序尚未发布,无法审核。

小程序尚未发布&#xff0c;无法审核。 先按照这篇文章把小程序审核通过&#xff0c;小程序版本审核未通过&#xff0c;需在开发者后台「版本管理—提交审核——小程序订单中心path」设置订单中心页path&#xff0c;请设置后再提交代码审核 小程序审核通过后&#xff0c;发布…

高效自学-网络安全(黑客技术)

一、网络安全应该怎么学&#xff1f; 1.计算机基础需要过关 这一步跟网安关系暂时不大&#xff0c;是进入it行业每个人都必须掌握的基础能力。 计算机网络计算机操作系统算法与数据架构数据库 Tips:不用非要钻研至非常精通&#xff0c;可以与学习其他课程同步进行。 2.渗透技…

Vue计算属性 computed

计算属性&#xff1a;常用于逻辑比较复杂的计算&#xff0c;根据已有的数据&#xff0c;计算出一个新的数据。计算属性具有缓存机制&#xff0c;复用性强&#xff0c;效率更高。 计算属性【简写方式】&#xff1a; <template><div>提现金额&#xff1a;<input …

【漏洞复现】XXL-JOB默认accessToken身份绕过远程命令执行漏洞

漏洞描述 xxl-job是一个中心式分布式的调度平台,调度中心和执行器解耦,执行器和业务代码耦合,代码的侵入性少,学习简单、开发简单、轻量级 XXL-JOB 是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线…

树莓派4B的测试记录(CPU、FFMPEG)

本文是用来记录树莓派 4B 的一些测试记录。 温度 下面记录中的风扇和大风扇是这样的&#xff1a; 为什么要用大风扇呢&#xff1f;因为小风扇在外壳上&#xff0c;气流通过外壳的珊格会有啸叫&#xff0c;声音不大但是很烦人&#xff0c;大风扇没这个问题&#xff0c;并且同样…

【计算机网络基础实验】实验二(补充内容)路由器的配置和静态路由

任务一 IP路由协议实现企业路由器通信 目录如下&#xff1a; 任务一 IP路由协议实现企业路由器通信一、实验目的&#xff1a;二、实验环境三、实验内容四、实验步骤1、路由器的基本配置&#xff08;1&#xff09;实验拓扑图&#xff08;2&#xff09;启动路由器&#xff08;3&a…

k8s-Pod控制器

一、Pod控制器 1.Pod控制器及其功用 Pod控制器&#xff0c;又称之为工作负载&#xff08;workload&#xff09;&#xff0c;是用于实现管理pod的中间层&#xff0c;确保pod资源符合预期的状态&#xff0c;pod的资源出现故障时&#xff0c;会尝试进行重启&#xff0c;当根据重启…

猫头虎博主第7期赠书活动:《计算机考研精炼1000题》

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

设计模式(3)-结构型模式

结构型模式 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式&#xff0c;前者采用继承机制来组织接口和类&#xff0c;后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低&#xff0c;满足“合成复用原则…

数据结构 - 全貌总结

目录 一. 前言 二. 分类 三. 常见的线性和非线性结构 一. 前言 数据结构是计算机存储、组织数据的方式。一种好的数据结构可以带来更高的运行或者存储效率。数据在内存中是呈线性排列的&#xff0c;但是我们可以使用指针等道具&#xff0c;构造出类似“树形”等复杂结构。 数…

ubuntu 安装 zsh、ohmyzsh并配置必要插件

下述记录是完成全部操作后回忆记录得来&#xff0c;或有不准确。我只记录安装中确实用到的指令&#xff0c;参考资料中有扩展内容&#xff0c;记录如下&#xff1a; ubuntu使用zsh终端并安装nerd font字体——nerd font字体不太好安装&#xff0c;使用fonts-powerline替代。 Ub…

Masked Image Training for Generalizable Deep Image Denoising 论文阅读笔记

CVPR2023 港科大&#xff08;广州&#xff09;发的一篇denoising的论文&#xff0c;作者里面有上海AILab的董超老师&#xff08;看introduction的时候看到有一段很像董超老师 Networks are slaching off 的论文的思想&#xff0c;说网络overfitting的时候学习了训练集的噪声模式…

NR DCI size alignment

DCI对齐在38.212 7.3.1.0 DCI size alignment 中讲述。 Step 0 CSS 下&#xff0c;DCI 0_0根据初始UL BWP 确定大小&#xff0c;DCI 1_0 根据CORESET0 或初始DL BWP&#xff08;没有CORESET 0时&#xff09; 确定大小 根据激活的UL/DL BWP 确定DCI 0_0和DCI 1_0 的size&…

DehazeNet: An End-to-End System for Single Image Haze Removal(端到端的去雾模型)

1、论文去雾总体思路 DehazeNet是2016年华南理工大学的研究者提出的一个端到端的深度学习模型&#xff0c;该模型主要通过输入的原始有雾图像拟合出该图所对应的medium transmission map&#xff08;透射率t值图&#xff09;&#xff0c;并使用引导滤波对t值进行refine&#x…