JVM CMS和G1执行过程比较

CMS

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。由于大部分 Java 应用主要集中在互联网网站以及基于浏览器的 B/S 系统的服务端,这类应用通常会较为关注服务的响应速度,希望系统的停顿时间尽可能少,CMS 收集器就非常符合这类应用的需求

从名字可以知道,CMS 收集器是基于标记 - 清除算法实现的,它的运作过程分为四个步骤:

  1. 初始标记(CMS initial mark)

    仅仅只是标记一下 GC Roots 能直接关联到的对象,速度很快,需要 Stop The World

  2. 并发标记(CMS concurrent mark)

    就是从 GC Roots 的直接关联对象开始遍历整个对象图的过程,耗时较长,但不需要停顿用户线程,可与垃圾收集器线程一起并发执行

  3. 重新标记(CMS remark)

    该阶段是为了修正并发标记期间,因用户程序运作而导致标记产生变动的那一部分对象的标记记录,这个阶段需要 Stop The World,而且停顿时间通常比初始阶段稍长一些,但也远比并发标记阶段的时间短

  4. 并发清除(CMS concurrent sweep)

    清理删除掉标记阶段判断已经死亡的对象,由于不需要移动存活对象,所有这个阶段可以和用户线程并发执行

由于整个过程中耗时最长的是并发标记和并发清除阶段,而这两个阶段都可以和用户线程并发执行,所以从总体上看,CMS 收集器内存回收过程是与用户线程一起并发执行的

CMS 收集器的主要优点就是:并发收集、低停顿,因此也称 CMS 收集器为并发低停顿收集器。但 CMS 还远未达到完美的程度,它至少有以下四个明显的缺点:

  1. 对处理器资源非常敏感

    在并发阶段,CMS 虽然不会导致用户线程停顿,但却会因为占用了一部分线程(或者说是处理器的计算能力)而导致应用程序变慢,降低吞吐量。处理器核心数在四个或以上那还好,如果不足四个,CMS 会占用将近一半的运算能力去执行收集器线程,这将导致用户程序的执行效率大幅降低

  2. 无法处理浮动垃圾

    在 CMS 的并发标记和并发清理阶段,由于用户线程继续运行,因此有可能会有新的垃圾对象产生。但这一部分垃圾对象是出现在标记结束之后,CMS 无法在当次收集中处理掉它们,只能留待下一次垃圾收集在清理,这一部分垃圾就称为浮动垃圾

  3. 可能会出现并发失败

    同样也是由于垃圾收集阶段用户线程还需持续执行,那就必须预留足够的内存空间供用户线程使用。因此 CMS 收集器不能像其他收集器那样等老年代几乎完全填满再进行收集,而必须预留一部分空间供并发收集时的程序运作使用,这部分空间的大小可以通过 -XX:CMSInitiatingOccu-pancyFraction 参数来设置。如果 CMS 运行期间预留的内存无法满足程序分配对象的需要,就会出现一次并发失败,这时虚拟机不得不启用预备方案:冻结用户线程,临时启用 Serial Old 收集器来重新进行老年代的垃圾收集,导致 Stop The World

  4. 大量空间碎片的产生

    CMS 是一款基于标记 - 清除算法实现的收集器,这也意味着收集结束时会产生大量空间碎片。为了解决这个问题,CMS 收集器提供了一个 -XX:+UseCMS-CompactAtFullCollection 开关参数,用于在收集结束后做一次内存整理,以及 -XX:CMSFullGCsBefore-Compaction 参数,要求 CMS 收集器在执行若干次不整理空间的 Full GC 之后,下一次 Full GC 前先做一次碎片整理

G1

Garbage First(G1)收集器是一款主要面向服务端应用的垃圾收集器,开创了收集器面向局部收集的设计思路和基于 Region 的内存布局形式。HotSpot 开发团队对 G1 收集器的期望就是能在将来替代 CMS 收集器,所以在 JDK9 发布之日,G1 便宣告取代 Parallel Scavenge 加 Parallel Old 组合,成为服务端模式下的默认垃圾收集器,而 CMS 则沦为不推荐使用

在过去,包括 CMS 在内,垃圾收集的范围要么是整个新生代,要么是整个老年代,再要么是整个 Java 堆。而 G1 可以面向堆内存任何部分来组成回收集(Collection Set,一般简称 CSet)进行回收,衡量标准是哪块内存中垃圾数量最多,回收收益最大,这就是 G1 收集器的 Mixed GC 模式

虽然 G1 也是基于分代收集理论设计,但其对内存布局与其他收集器有明显差异。G1 把连续的 Java 堆划分成多个大小相等的独立区域(Region),每一个 Region 可以根据需要扮演新生代的 Eden 空间、Survivor 空间、老年代空间等等。收集器能对扮演不同角色的 Region 采用不同的策略处理

Region 中还有一类特殊的 Humongous 区域,专门用来存储大对象。只要该对象大小超过一半的 Region 的容量即可判定为大对象。而对于那些超过整个 Region 容量的超级大对象,将会被存放在 N 个连续的 Humongous Region 之中,G1 的大多数行为都把 Humongous Region 作为老年代的一部分来看待

停顿时间模型的意思是能够支持指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间大概率不超过 M 毫秒这么一个目标。G1 收集器作为 CMS 收集器的替代者,自然可以实现这个目标

G1 之所以能建立起可预测的停顿时间模型,是因为它将 Region 作为单词回收的最小单元,即每次收集到的内存空间都是 Region 大小的整数倍,这样可以有计划地避免进行全区域的垃圾收集。G1 收集器还可以跟踪每个 Region 的垃圾堆积的“价值”大小,即回收所获得的空间大小以及所需时间,并在后台维护一个优先级列表,每次根据用户设置的允许收集停顿时间(使用 -XX:MaxGCPauseMillis 指定),优先处理回收价值最大的 Region。这种使用 Region 划分内存空间,以及具有优先级的区域回收方式,保证了 G1 收集器在有限的时间内获取尽可能高的收集效率

G1 收集器的设计理念看似无太多惊人之处,其实有很多关键的细节问题需要解决:

  • 如何解决跨 Region 引用对象?

    这个问题的解决思路可以使用之前提到过的记忆集来处理,但由于每个 Region 都要维护自己的记忆集,因此实现更加复杂,而且内存占用负担也更重

  • 并发标记阶段如何保证收集线程与用户线程互不干扰?

    对应该问题,CMS 采用增量更新算法解决,而 G1 采用原始快照算法解题。另外,G1 还为每一个 Region 设计了两个名为 TAMS(Top At Mark Start)的指针,用于在并发回收过程中新对象的内存分配。G1 收集器默认在这个地址以上的对象是存活的,不会纳入回收范围

  • 如何建立起可靠的停顿预测模型?

    G1 收集器的停顿时间模型是以衰减均值(Decaying Average)为理论基础实现的。衰减均值是指它会比普通的平均值更容易受新数据影响,因此,Region 的统计状态越新,越能决定其回收的价值

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

  1. 初始标记

    仅仅标记一下 GC Roots 能直接关联的对象,并修改 TAMS 指针的值。该阶段需停顿线程,但耗时很短,而且是借进行 Minor GC 时同步完成的,实际上并没有额外的停顿

  2. 并发标记

    从 GC Roots 开始对堆中对象进行可达性分析,找出要回收对象。该阶段耗时较长,但可与用户程序并发执行。当扫描完成后,还要重新处理 SATB 记录下在并发时有引用变动的对象

  3. 最终标记

    用户线程短暂暂停,处理并发阶段结束后遗留下来的少量 SATB 记录

  4. 筛选回收

    更新 Region 统计数据,对各个 Region 的回收价值和成本进行排序,根据用户所期望的停顿时间制定回收计划,然后把要回收的那一部分 Region 的存活对象复制到空的 Region 中,再清理掉整个旧 Region 的全部空间。这里涉及到存活对象的移动,必须暂停用户线程

G1 和 CMS 都非常关注停顿时间控制,毫无疑问,可以由用户指定期望的停顿时间是 G1 收集器的一大杀手锏。G1 收集器经常被拿来和 CMS 收集器比较,从长远来看,G1 收集器肯定是会取代 CMS 收集器的

除了更先进的设计理念,单从传统的算法理论来看,G1 从整体来看是基于标记 - 整理算法实现,而从局部来看(两个 Region 之间)又是基于标记 - 复制算法实现,这意味着 G1 不会产生内存碎片。但 G1 并非全方面碾压 CMS,G1 由于其复杂的内部细节实现,使得垃圾收集时的内存占用和程序运行时的额外执行负载都要比 CMS 高。使用哪款收集器,往往要针对具体场景才能做定量比较,目前在小内存应用上 CMS 的表现大概率会优于 G1,而在大内存应用上 G1 则占有优势,这个平衡点通常在 6GB ~ 8GB 之间。当然,随着 HotSpot 开发者对 G1 的持续优化,最终胜利的天平必定回向 G1 倾斜



作者:CoderZS
链接:https://www.jianshu.com/p/1a6c00173cd1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python in Visual Studio Code 2023年10月发布

排版:Alan Wang 我们很高兴地宣布 Visual Studio Code 的 Python 和 Jupyter 扩展于 2023 年 10 月发布! 此版本包括以下公告: Python 调试器扩展更新弃用 Python 3.7 支持Pylint 扩展更换时的 Lint 选项Mypy 扩展报告的范围和守护程序模式G…

后端解决跨域(极速版)

header(Access-Control-Allow-Origin: *); header(Access-Control-Allow-Methods:*); 代表接收全部的请求,"POST,GET"//允许访问的方式 指定域,如http://172.20.0.206//宝塔的域名,注意不是:http://wang.jingyi.icu等…

一文图解Golang管道Channel

在 Go 语言发布之前,很少有语言从底层为并发原语提供支持。大多数语言还是支持共享和内存访问同步到 CSP 的消息传递方法。Go 语言算是最早将 CSP 原则纳入其核心的语言之一。内存访问同步的方式并不是不好,只是在高并发的场景下有时候难以正确的使用&am…

【移植代码】matlab.engine报错、numpy+mkl安装、Qt platform plugin报错总结

文章目录 numpy报错numpy安装PyQt5报错matlab.engine无法加载确认配置版本进行配置 matlab文件路径缺失vscode无法debug3.7以下版本总结 今天的任务是复现师姐的代码,代码在服务器的环境下可以跑,而我要做的,就是将环境和源码配置好&#xff…

JavaScript使用类-模态窗口

**上节课我们为这个项目获取了一些DOM元素,现在我们可以继续;**这个模态窗口有一个hidden类,这个类上文我们讲了,他的display为none;如果我们去除这个hidden的话,就可以让这个模态窗口展现出来。如下 cons…

yolov5加关键点回归

文章目录 一、数据1)数据准备2)标注文件说明 二、基于yolov5-face 修改自己的yolov5加关键点回归1、dataloader,py2、augmentations.py3、loss.py4、yolo.py 一、数据 1)数据准备 1、手动创建文件夹: yolov5-face-master/data/widerface/tr…

【postgresql】

看到group by 1,2 和 order by 1, 2。看不懂,google,搜到了Stack Overflow 上有回答 What does SQL clause “GROUP BY 1” mean? 大概意思就是,group by, order by 后面跟数字,指的是 selec…

git命令笔记

git命令笔记 前言:git对于软件开发和协作的重要性不言而喻,在企业开发中,git命令和linux命令的使用同样重要。作为开发者,需要牢记并熟练使用常见的git命令 git工作流程图 命令如下: clone(克隆&#xf…

虹科方案|国庆出游季,古建筑振动监测让历史古迹不再受损

全文导读: 国庆长假即将到来,各位小伙伴是不是都做好了出游计划呢?今年中秋、国庆“双节”连休八天,多地预计游客接待量将创下新高,而各地的名胜古迹更是人流爆满。迎接游客的同时,如何保障历史古迹不因巨大…

ATFX汇市:美国9月CPI数据来袭,机构预期年率增速将继续回落

ATFX汇市:今日20:30,美国劳工部将公布9月未季调CPI年率增速,前值为3.7%,预期值3.6%;9月未季调核心CPI年率,同一时间公布,前值为4.3%,预期值4.1%。无论是名义CPI增速还是核心CPI增速&…

vue配置@路径

第一步:安装path,如果node_module文件夹中有path就不用安装了 安装命令:npm install path --save 第二步:在vue.config.js文件(如果没有就新建)中配置 const path require("path"); function …

el-data-picker限制日期可选范围

<el-date-pickerclass"date"v-model"date"type"date"change"dateChange"value-format"yyyy-MM-dd"format"yyyy-MM-dd"placeholder"选择日期":picker-options"datePickerOptions"></…

基于SpringBoot的大学城水电管理系统

目录 前言 一、技术栈 二、系统功能介绍 管理员模块的实现 领用设备管理 消耗设备管理 设备申请管理 状态汇报管理 用户模块的实现 设备申请 状态汇报 用户反馈 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛…

【Java 进阶篇】JavaScript 介绍及其发展史

JavaScript是一门广泛应用于Web开发的编程语言。它是一种高级的、解释性的脚本语言&#xff0c;主要用于改善用户与Web页面的互动体验。本篇博客将为你详细介绍JavaScript的基础知识、历史背景和它在Web开发中的重要作用。我们还将讨论JavaScript的发展史&#xff0c;从它的起源…

【Java 进阶篇】JavaScript二元运算符详解

JavaScript是一门多用途的编程语言&#xff0c;它支持各种运算符&#xff0c;包括二元运算符。二元运算符用于执行两个操作数之间的操作&#xff0c;这两个操作数通常是变量、值或表达式。在本篇博客中&#xff0c;我们将详细探讨JavaScript的二元运算符&#xff0c;包括它们的…

设计模式-状态模式

介绍 一个对象有状态变化每次状态变化都会触发一个逻辑不能总是用if else来控制 示例 交通信号灯不同颜色的变化 UML类图 传统UML类图 简化后的UML类图 代码演示 // 状态&#xff08;红灯、绿灯、黄灯&#xff09; class State {constructor(color) {this.color col…

A股风格因子看板 (2023.10 第04期)

该因子看板跟踪A股风格因子&#xff0c;该因子主要解释沪深两市的市场收益、刻画市场风格趋势的系列风格因子&#xff0c;用以分析市场风格切换、组合风格暴露等。 今日为该因子跟踪第04期&#xff0c;指数组合数据截止日2023-09-30&#xff0c;要点如下 近1年A股风格因子检验统…

一站式解决方案:Qt 跨平台开发灵活可靠

一站式解决方案&#xff1a;Qt 跨平台开发灵活可靠 Qt 是一种跨平台开发工具&#xff0c;为开发者提供了一站式解决方案。无论您的项目目标是 Windows、Linux、macOS、嵌入式系统还是移动平台&#xff0c;Qt 都能胜任。这种跨平台的特性不仅节省开支&#xff0c;还推动了战略的…

CTF Misc(3)流量分析基础以及原理

前言 流量分析在ctf比赛中也是常见的题目&#xff0c;参赛者通常会收到一个网络数据包的数据集&#xff0c;这些数据包记录了网络通信的内容和细节。参赛者的任务是通过分析这些数据包&#xff0c;识别出有用的信息&#xff0c;例如登录凭据、加密算法、漏洞利用等等 工具安装…

【SQL】MySQL中的索引,索引优化

索引是存储引擎用来快速查询记录的一种数据结构&#xff0c;按实现方式主要分为Hash索引和B树索引。 按功能划分&#xff0c;主要有以下几类 单列索引指的是对某一列单独建立索引&#xff0c;一张表中可以有多个单列索引 1. 单列索引 - 普通索引 创建索引&#xff08;关键字i…