【Java】图解 JVM 垃圾回收(二):垃圾收集器、Full GC

图解 JVM 垃圾回收(二)

  • 1.垃圾收集器
    • 1.1 内存分配与回收策略
    • 1.2 Serial 收集器
    • 1.3 Parallel Scavenge 收集器
    • 1.4 ParNew 收集器
    • 1.5 CMS 收集器
    • 1.6 G1 收集器
  • 2.Full GC 的触发条件

1.垃圾收集器

Java 虚拟机提供了多种垃圾回收器,每种回收器有其特定的用途和优势。以下是常见的垃圾回收器:

在这里插入图片描述
连线表示垃圾收集器可以配合使用。

  • 单线程与多线程:单线程指的是垃圾收集器只使用一个线程进行收集,而多线程使用多个线程。
  • 串行与并行:串行指的是垃圾收集器与用户程序交替执行,这意味着在执行垃圾收集的时候需要停顿用户程序;并行指的是垃圾收集器和用户程序同时执行。除了 CMS 和 G1 之外,其它垃圾收集器都是以串行的方式执行。

1.1 内存分配与回收策略

JVM 在进行 GC 时,并非每次都对堆内存(新生代、老年代;方法区)区域一起回收的,大部分时候回收的都是指新生代

针对 HotSpot VM 的实现,它里面的 GC 按照回收区域又分为两大类:部分收集Partial GC),整堆收集Full GC)。

  • 部分收集:不是完整收集整个 Java 堆的垃圾收集。其中又分为:
    • 新生代收集Minor GC / Young GC):只是新生代的垃圾收集。
    • 老年代收集Major GC / Old GC):只是老年代的垃圾收集。目前,只有 CMS GC 会有单独收集老年代的行为。很多时候 Major GC 会和 Full GC 混合使用,需要具体分辨是老年代回收还是整堆回收。
    • 混合收集Mixed GC):收集整个新生代以及部分老年代的垃圾收集。目前只有 G1 GC 会有这种行为。
  • 整堆收集:收集整个 Java 堆和方法区的垃圾。

1.2 Serial 收集器

  • -XX:+UseSerialGC
  • -XX:+UseSerialOldGC

Serial 是一个单线程收集器了。它的 “单线程” 的意义不仅仅意味着它只会使用一条垃圾收集线程去完成垃圾收集工作,更重要的是它在进行垃圾收集工作的时候必须暂停其他所有的工作线程( “Stop The World” ),直到它收集结束。

在这里插入图片描述

  • Serial 收集器由于没有线程交互的开销,自然可以获得很高的单线程收集效率。
  • Serial Old 收集器是 Serial 收集器的老年代版本,它同样是一个单线程收集器。它主要有两大用途:一种用途是在 JDK 1.5 以及以前的版本中与 Parallel Scavenge 收集器搭配使用,另一种用途是作为 CMS 收集器的后备方案。
  • 新生代采用 复制 算法,老年代采用 标记-整理 算法。

1.3 Parallel Scavenge 收集器

  • -XX:+UseParallelGC(新生代)
  • -XX:+UseParallelOldGC(老年代)

Parallel 收集器其实就是 Serial 收集器的 多线程版本,除了使用多线程进行垃圾收集外,其余行为(控制参数、收集算法、回收策略等等)和 Serial 收集器类似。默认的收集线程数CPU 核数 相同,当然也可以用参数(-XX:ParallelGCThreads)指定收集线程数,但是一般不推荐修改。

Parallel Scavenge 收集器关注点是 吞吐量(高效率的利用 CPU)。CMS 等垃圾收集器的关注点更多的是用户线程的 停顿时间(提高用户体验)。所谓吞吐量就是 CPU 中用于运行用户代码的时间与 CPU 总消耗时间的比值。Parallel Scavenge 收集器提供了很多参数供用户找到最合适的停顿时间或最大吞吐量,如果对于收集器运作不太了解的话,可以选择把内存管理优化交给虚拟机去完成也是一个不错的选择。

新生代采用 复制 算法,老年代采用 标记-整理 算法。

Parallel Old 收集器是 Parallel Scavenge 收集器的老年代版本。使用 多线程标记-整理 算法。在注重吞吐量以及 CPU 资源的场合,都可以优先考虑 Parallel Scavenge 收集器和 Parallel Old 收集器(JDK 8 默认的新生代和老年代收集器)。

1.4 ParNew 收集器

  • -XX:+UseParNewGC(新生代)

ParNew 收集器其实跟 Parallel 收集器很类似,区别主要在于它可以和 CMS 收集器配合使用。

新生代采用 复制 算法。

1.5 CMS 收集器

  • -XX:+UseConcMarkSweepGC(老年代)

CMS(Concurrent Mark Sweep),Mark Sweep 指的是 标记-清除 算法。

CMS 收集器是一种以获取 最短回收停顿时间 为目标的收集器。它非常符合在注重用户体验的应用上使用,它是 HotSpot 虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作

它的运作过程相比于前面几种垃圾收集器来说更加复杂一些。整个过程分为四个步骤:

  • 初始标记: 暂停所有的其他线程(STW),并记录下 GC Roots 直接能引用的对象,速度很快。
  • 并发标记: 并发标记阶段就是从 GC Roots 的直接关联对象开始遍历整个对象图的过程, 这个过程耗时较长但是不需要停顿用户线程, 可以与垃圾收集线程一起并发运行。因为用户程序继续运行,可能会有导致已经标记过的对象状态发生改变。
  • 重新标记: 重新标记阶段就是为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的标记记录(主要是处理漏标问题),这个阶段的停顿时间一般会比初始标记阶段的时间稍长,远远比并发标记阶段时间短。主要用到三色标记里的增量更新算法做重新标记。
  • 并发清理: 开启用户线程,同时 GC 线程开始对未标记的区域做清扫。这个阶段如果有新增对象会被标记为黑色不做任何处理。
  • 并发重置:重置本次 GC 过程中的标记数据。

在这里插入图片描述

CMS 主要优点:并发收集、低停顿。但是它有下面几个明显的缺点:

  • ⭕ 对 CPU 资源敏感(会和服务抢资源)。
  • ⭕ 无法处理浮动垃圾(在并发标记和并发清理阶段又产生垃圾,这种浮动垃圾只能等到下一次 GC 再清理了)。
  • ⭕ 它使用的 “标记-清除” 回收算法会导致收集结束时会有大量空间碎片产生,通过参数 -XX:+UseCMSCompactAtFullCollection 可以让 JVM 在执行完标记清除后再做整理,往往出现老年代空间剩余,但无法找到足够大连续空间来分配当前对象,不得不提前触发一次 Full GC。
  • ⭕ 执行过程中的不确定性,会存在上一次垃圾回收还没执行完,然后垃圾回收又被触发的情况,特别是在并发标记和并发清理阶段会出现,一边回收,系统一边运行,也许没回收完就再次触发 Full GC,也就是 “Concurrent Mode Failure”,此时会进入 “Stop The World”,用 Serial Old 垃圾收集器来回收。

1.6 G1 收集器

G1(Garbage-First)是一款面向服务端应用的垃圾收集器,在多 CPU 和大内存的场景下有很好的性能。

堆被分为新生代和老年代,其它收集器进行收集的范围都是整个新生代或者老年代,而 G1 可以直接对新生代和老年代一起回收。G1 把堆划分成多个大小相等的 独立区域Region),新生代和老年代不再物理隔离。
在这里插入图片描述
通过引入 Region 的概念,从而将原来的一整块内存空间划分成多个的小空间,使得每个小空间可以单独进行垃圾回收。这种划分方法带来了很大的灵活性,使得可预测的停顿时间模型成为可能。通过记录每个 Region 垃圾回收时间以及回收所获得的空间(这两个值是通过过去回收的经验获得),并维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的 Region。

每个 Region 都有一个 Remembered Set,用来记录该 Region 对象的引用对象所在的 Region。通过使用 Remembered Set,在做可达性分析的时候就可以避免全堆扫描。

G1 收集器的运作大致可划分为以下几个步骤:

  • 初始标记Initial Marking):仅仅只是标记一下 GC Roots 能直接关联到的对象。
  • 并发标记Concurrent Marking):从 GC Roots 开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。
  • 最终标记Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的 SATB(Snapshot At The Beginning,原始快照)记录。
  • 筛选回收Live Data Counting and Evacuation):负责更新 Region 的统计数据,对各个 Region 的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个 Region 构成回收集,然后把决定回收的那一部分 Region 的存活对象复制到空的 Region 中,再清理掉整个旧 Region 的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。

它具备以下特点:

  • 并行与并发:G1 能充分利用 CPU、多核环境下的硬件优势,使用多个 CPU(CPU 或者 CPU 核心)来缩短 Stop-The-World 停顿时间。部分其他收集器原本需要停顿 Java 线程执行的 GC 动作,G1 收集器仍然可以通过并发的方式让 Java 程序继续执行。
  • 分代收集:虽然 G1 可以不需要其他收集器配合就能独立管理整个 GC 堆,但是还是保留了分代的概念。
  • 空间整合:与 CMS 的 “标记-清除” 算法不同,G1 从整体来看是基于 “标记-整理” 算法实现的收集器;从局部上来看是基于 “标记-复制” 算法实现的。
  • 可预测的停顿:这是 G1 相对于 CMS 的另一个大优势,降低停顿时间是 G1 和 CMS 共同的关注点,但 G1 除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过 N 毫秒。

在这里插入图片描述
G1 收集器在后台维护了一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的 Region(这也就是它的名字 Garbage-First 的由来)。这种使用 Region 划分内存空间以及有优先级的区域回收方式,保证了 G1 收集器在有限时间内可以尽可能高的收集效率(把内存化整为零)。

从 JDK 9 开始,G1 垃圾收集器成为了默认的垃圾收集器

2.Full GC 的触发条件

对于 Minor GC,其触发条件非常简单,当 Eden 空间满时,就将触发一次 Minor GC。而 Full GC 则相对复杂,有以下条件:

  • 调用 System.gc() 只是建议虚拟机执行 Full GC,但是虚拟机不一定真正去执行。不建议使用这种方式,而是让虚拟机管理内存。
  • 老年代空间不足。老年代空间不足的常见场景为前文所讲的:大对象直接进入老年代、长期存活的对象进入老年代等。为了避免以上原因引起的 Full GC,应当尽量不要创建过大的对象以及数组。除此之外,可以通过 -Xmn 虚拟机参数调大新生代的大小,让对象尽量在新生代被回收掉,不进入老年代。还可以通过 -XX:MaxTenuringThreshold 调大对象进入老年代的年龄,让对象在新生代多存活一段时间。
  • 空间分配担保失败。使用复制算法的 Minor GC 需要老年代的内存空间作担保,如果担保失败会执行一次 Full GC。
  • JDK 1.7 及以前的永久代空间不足(1.7 之后元空间不足)。在 JDK 1.7 及以前,HotSpot 虚拟机中的方法区是用永久代实现的,永久代中存放的为一些 Class 的信息、常量、静态变量等数据。当系统中要加载的类、反射的类和调用的方法较多时,永久代可能会被占满,在未配置为采用 CMS GC 的情况下也会执行 Full GC。如果经过 Full GC 仍然回收不了,那么虚拟机会抛出 java.lang.OutOfMemoryError。为避免以上原因引起的 Full GC,可采用的方法为增大永久代空间或转为使用 CMS GC。
  • Concurrent Mode Failure。执行 CMS GC 的过程中同时有对象要放入老年代,而此时老年代空间不足(可能是 GC 过程中浮动垃圾过多导致暂时性的空间不足),便会报 Concurrent Mode Failure 错误,并触发 Full GC。

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

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

相关文章

postgresql 文件结构(一) 数据库、表对应的文件

1、问题 甲方要求提供数据库数据量大小,由于各个业务数据库共用一个postgres,因此想把每个数据库占用的空间都统计一下。 2、查找物理存储文件目录 如下图所示,可以查询表、库的物理存储文件名称 -- 查询表对应的文件 select oid,relname…

c编译器学习02:chibicc文档翻译

目的 先粗略地看一遍作者的书籍。 原文档地址 https://www.sigbus.info/compilerbook# “低レイヤを知りたい人のためのCコンパイラ作成入門” 为想了解底层的人准备的C编译器制作入门 Rui Ueyama ruiucs.stanford.edu 2020-03-16 作者简介 https://www.sigbus.info/ 植山…

【前端素材】几款实用的后台管理系统html模板(附带源码)

一、需求分析 后台管理系统是一种用于管理网站、应用程序或系统的工具,它通常作为一个独立的后台界面存在,供管理员或特定用户使用。下面详细分析后台管理系统的定义和功能: 1. 定义 后台管理系统是一个用于管理和控制网站、应用程序或系统…

flink多流操作(connect cogroup union broadcast)

flink多流操作 1 分流操作2 connect连接操作2.1 connect 连接(DataStream,DataStream→ConnectedStreams)2.2 coMap(ConnectedStreams → DataStream)2.3 coFlatMap(ConnectedStreams → DataStream) 3 union操作3.1 u…

一文搞懂LDO !

7.LDO 1.原理 通过运放调节P-MOS的输出 低压差: 输出压降比较低,例如输入3.3V,输出可以达到3.2V。 线性: LDO内部的MOS管工作于线性状态。(可变电阻区) 稳压器: 说明了LDO的用途是用来给电…

LeetCode.590. N 叉树的后序遍历

题目 590. N 叉树的后序遍历 分析 我们之前有做过LeetCode的 145. 二叉树的后序遍历,其实对于 N 叉树来说和二叉树的思路是一模一样的。 二叉树的后序遍历是【左 右 根】 N叉树的后序遍历顺序是【孩子 根】,你可以把二叉树的【左 右 根】想象成【孩子…

Win11专业版安装集成了谷歌框架的安卓子系统,包含谷歌商店

1.摘要 上一篇博客讲述了使用微软商店安装安卓子系统的教程 https://blog.csdn.net/RudeTomatoes/article/details/135958882 上述方法的优点是安装过程简单,但是,由于Windows安卓子系统是微软与亚马逊联合开发,默认没有安装谷歌框架。我尝试…

[SwiftUI]自定义下划线

系统有一个下划线修饰,但最低只支持到iOS16。 extension View {available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)public func underline(_ isActive: Bool true, pattern: Text.LineStyle.Pattern .solid, color: Color? nil) -> some View} 下…

金融帝国实验室(CapLab)官方更新_V9.1.62版本(2024年第10次)

〖金融帝国实验室〗(Capitalism Lab)游戏更新记录(2024年度) ————————————— ◎游戏开发:Enlight Software Ltd.(微启软件有限公司) ◎官方网站:https://www.capitalism…

IBM Spectrum LSF Process Manager 在共享分布式计算环境中运行和管理业务关键工作流程

IBM Spectrum LSF Process Manager 设计、记录和运行复杂的计算工作流 亮点 ● 快速创建复杂的分布式工作流 ● 开发可重复的最佳实践 ● 自信地运行关键工作流程 ● 提高流程可靠性 IBM Spectrum LSF Process Manager 使您能够设计和自动化计算或分析流程, 捕获…

http相关概念以及apache的功能

概念 互联网:是网络的网络,是所有类型网络的母集 因特网:世界上最大的互联网网络 万维网:www (不是网络,而是数据库)是网页与网页之间的跳转关系 URL:万维网使用统一资源定位符,…

Spring Cloud微服务网关Zuul灰度发布入门实战

一、灰度发布 灰度发布是指在系统迭代的时候一种平滑过度上线发布方式。灰度发布是在原有的系统的基础上面,额外增加一个新版本,这个新版本包含新上线的需要验证的功能,通过负载均衡引入部分流量到新版本的应用上,如果在这个过程…

Mysql数据库主从集群从库Slave因为RelayLog过多过大引起服务器硬盘爆满生产事故实战解决

Mysql数据库主从集群从库slave因为RelayLog过多过大引起从库服务器硬盘爆满生产事故实战解决 一、MySQL数据库主从集群概念 MySQL数据库主从集群是一种高可用性和读写分离的数据库架构,它基于MySQL的复制(Replication)技术来同步数据。在主…

力扣题目训练(17)

2024年2月10日力扣题目训练 2024年2月10日力扣题目训练551. 学生出勤记录 I557. 反转字符串中的单词 III559. N 叉树的最大深度241. 为运算表达式设计优先级260. 只出现一次的数字 III126. 单词接龙 II 2024年2月10日力扣题目训练 2024年2月10日第十七天编程训练,今…

无人机数据链技术,无人机数据链路系统技术详解,无人机数传技术

早期的无人机更多的为军事应用服务,如军事任务侦查等,随着技术和社会的发展,工业级无人机和民用无人机得到快速的发展,工业级无人机用于农业植保、地理测绘、电力巡检、救灾援助等;民用无人机用于航拍、物流等等领域。…

Codeforces Round 928 (Div. 4)(A、B、C、D、E、G)

文章目录 ABCDEG A 统计A、B输出 #include <bits/stdc.h> #define int long long #define rep(i,a,b) for(int i (a); i < (b); i) #define fep(i,a,b) for(int i (a); i > (b); --i) #define pii pair<int, int> #define ll long long #define db doubl…

springboot+flowable 使用方式

创建flowble制定流程图 登录flowalbe 制定流程图 进入建模器应用程序 创建流程图 分配用户 下载流程图 使用springboot 调用flowable /*** 导入流程图老师流程*/Testvoid startTeacherApprover(){Deployment deploy repositoryService.createDeployment().addClasspathRes…

2024,“热辣滚烫”的春节热点!

2024春节&#xff0c;都发生了哪些热点事件&#xff1f; 搜肠刮肚比较难&#xff0c;于是百度了一下&#xff0c;但结果难以令人满意&#xff0c;不同博主的眼中都有不同的热点。 这才想起&#xff0c;我们早已生活在自己的“信息茧房”中&#xff0c;每个人都有自己关注的热…

GZ036 区块链技术应用赛项赛题第9套

2023年全国职业院校技能大赛 高职组 “区块链技术应用” 赛项赛卷&#xff08;9卷&#xff09; 任 务 书 参赛队编号&#xff1a; 背景描述 随着异地务工人员的增多&#xff0c;房屋租赁成为一个广阔是市场&#xff1b;目前&#xff0c;现有技术中的房屋租赁是由…

天拓四方:如何通过工业智能网关进行设备数据采集,以及其带来的优势

工业智能网关是一种嵌入式设备&#xff0c;设计用于连接和管理各种工业设备和系统。它充当设备间的通信中介&#xff0c;实现数据采集、转换和传输。与传统的网关相比&#xff0c;工业智能网关具有更强的数据处理能力和更广泛的连接性&#xff0c;可以支持多种通信协议。在当今…