JVM 性能分析 —— CMS 老年代并发 GC 触发条件与压缩式 GC (升级为 Full GC)触发条件

news/2024/9/18 23:06:57/ 标签: jvm, java, CMS, 并发收集, 压缩式GC, Full GC, 触发条件

文章目录

    • CMS 触发老年代 GC 条件
      • foreground collector(前台收集)
      • background collector(后台收集)
    • MSC(mark-sweep-compact 压缩式 GC)

CMS__GC__2">CMS 触发老年代 GC 条件

先看看触发老年代GC的条件。CMS GC 在实现上分成 foreground collector(前台收集)和 background collector(后台收集)。前台收集相对比较简单,后台收集比较复杂,情况比较多。不管是 foreground collector 还是 background collector 使用的都是 mark-sweep 算法,分阶段进行标记清理,优点很明显-低延时,但最大的缺点是存在碎片,内存空间利用率低。

CMS GC 可以触发压缩式 GC(标记压缩算法),就是触发了 Full GC,否则还是正常的并发收集。压缩式 GC 这个过程就必须要等待内存分配成功后业务线程才能继续往下面走,因此整个过程必须 STW。

foreground collector(前台收集)

  • foreground collector 触发条件比较简单,就是没有空间分配对象时,就会触发一次 CMS 并发 GC 收集来进行空间回收。

background collector(后台收集)

CMS 大家都知道是并发收集器,一般常见的并发收集就是正常情况下触发 background collector 的 CMS GC,对业务影响很小。当并发模式搞不定了,就会触发 Full GC,这个回收过程业务线程是不可用的,这时候其实就是触发了 FullGC。

background collector 是通过 CMS 后台线程不断的去扫描,主要是判断是否符合 background collector 的触发条件,一旦有符合的情况,就会进行一次 background 的收集。(参考资料)

  • CMSWaitDuration 参数是用于控制 CMS 后台线程扫描的间隔周期,每次扫描去判断是否满足 CMS background collector 的触发条件以开启一次并发收集CMSWaitDuration 默认值为 2000 毫秒,即 2 秒。

  • 触发条件一:GC cause 是 gclocker 并且配置了 GCLockerInvokesConcurrent 参数、或者 GC cause 是javalangsystemgc(就是 System.gc()调用)并且配置了 ExplicitGCInvokesConcurrent 参数,这时会触发一次 background collector。

    GCLockerInvokesConcurrent 参数用于控制当 GC Locker 被占用时是否触发并发 GC 收集。默认值为 false,即当 GC Locker 被占用时,CMS 收集器会等待 GC Locker 被释放后再进行 Full GC。如果设置为 true,当 GC Locker 被占用时,CMS 收集器会触发并发 GC 收集,而不是等待 GC Locker 被释放后再进行 Full GC

    ExplicitGCInvokesConcurrent 参数用于控制是否在应用程序调用 System.gc() 时触发并发 GC 收集。默认值为 false,即在应用程序调用 System.gc() 时会触发一次 Full GC。如果设置为 true,当应用程序调用 System.gc() 时,CMS 收集器会触发一次并发 GC 收集,而不是 Full GC

  • 触发条件二:根据统计数据动态计算(前提是未配置 UseCMSInitiatingOccupancyOnly 时),会根据统计数据动态判断是否需要进行一次 CMS GC。判断逻辑是,如果预测 CMS GC 完成所需要的时间大于预计的老年代将要填满的时间,则进行并发 GC。 这些判断是需要基于历史的 CMS GC 统计指标,然而,第一次 CMS GC 时,统计数据还没有形成,是无效的,这时会跟据 Old Gen 的使用占比来判断是否要进行 GC。

    UseCMSInitiatingOccupancyOnly 参数用于控制是否仅使用设定的 CMS 初始占用率作为触发 CMS 并发 GC 收集的条件。默认值为 false,即 CMS 收集器会使用其他一些条件来决定何时启动并发收集。如果设置为 true,CMS 收集器将仅使用设定的 CMS 初始占用率作为启动并发收集触发条件,不考虑其他因素。

  • 触发条件三:根据 Old Gen 使用占比来触发。当 Old Gen 的使用占比超过指定阈值(CMSInitiatingOccupancyFraction )就进行 GC。

    CMSInitiatingOccupancyFraction 参数用于设置触发 CMS GC 的老年代占用率阈值。即当老年代使用率超过该参数设定阈值,就触发 GC。

  • 触发条件四:在两代的 GC 体系中,主要指的是 Young GC 是否会失败。如果 Young GC 已经失败或者可能会失败,JVM 就认为需要进行一次 CMS 并发 GC。

    Young GC 为什么会失败一般是因为 Old Gen 没有足够的空间来容纳晋升的对象,比如常见的 “promotion failed”;

    可能失败是通过判断当前 Old Gen 剩余的空间大小是否足够容纳 Young GC 晋升的对象大小。 Young GC 到底要晋升多少是无法提前知道的,因此,这里通过统计平均每次 Young GC 晋升的大小和当前 Young GC 可能晋生的最大大小来进行比较;

  • 触发条件五:配置了 CMSClassUnloadingEnabled 参数,在 meta space 进行扩容时就会进行一次 CMS 并发 GC。(经常会有应用启动不久,Old Gen 空间占比还很小的情况下,进行了一次 CMS GC,让你很莫名其妙,其实就是这个原因导致的。)

    CMSClassUnloadingEnabled 参数用于控制 CMS GC 是否启用类卸载功能。类卸载是 JVM 在 GC 过程中释放不再使用的类元数据的过程。这样可以减少永久代或元空间的占用,从而提高内存的利用效率。

    • CMSClassUnloadingEnabled 参数默认为 true,CMS GC 会在 GC 过程中执行类卸载。
    • CMSClassUnloadingEnabled 参数设置为 false 时,CMS GC 不会执行类卸载。

MSC(mark-sweep-compact 压缩式 GC)

CMS 在每次进行 GC 之前,会先判断是否需要进行一次压缩式 GC。此压缩式 GC,CMS 使用的是跟 Serial Old GC 一样的 LISP2 算法,其使用 mark-compact 来做 Full GC,一般称之为 MSC(mark-sweep-compact),它收集的范围是 Java 堆的 Young Gen 和 Old Gen 以及 metaspace(元空间)。

CMS 在进行 GC 之前,会先判断是进行 mark-sweep 的 CMS GC,还是进行 mark-sweep-compact 的 Full GC。主要的判断依据是:(参考资料)

  • 前提条件:需要开启 UseCMSCompactAtFullCollection(-XX:UseCMSCompactAtFullCollection=true 或 -XX:+UseCMSCompactAtFullCollection),默认情况下是开启的。该参数决定了在某个触发条件下是否是触发压缩式 GC,以减少内存碎片。

  • 触发条件一:在上次 Full GC 后,又发生的 Full GC 次数大于等于 CMSFullGCsBeforeCompaction 参数设定的阈值,就表示可以进行一次压缩式的 Full GC

    CMSFullGCsBeforeCompaction 参数用于控制在多少次 Full GC 之后触发一次内存压缩操作。默认值为 0,表示在每次 Full GC 时都会触发内存压缩。

  • 触发条件二:用户请求式触发导致的 GCCause,就是 javalangsystemgc(即 System.gc())或者 jvmtiforce_gc(即 JVMTI 方式的强制 GC),意味着只要是 System.gc(前提没有配置 ExplicitGCInvokesConcurrent 参数)调用或者 JVMTI 方式的强制 GC 都会进行一次压缩式的 Full GC

    ExplicitGCInvokesConcurrent 参数用于控制是否在应用程序调用 System.gc() 时触发并发 GC 收集。默认值为 false,即在应用程序调用 System.gc() 时会触发一次 Full GC。如果设置为 true,当应用程序调用 System.gc() 时,CMS 收集器会触发一次并发 GC 收集,而不是 Full GC

  • 触发条件三:在两代的 GC 体系中,主要指的是 Young GC 是否会失败。如果 Young GC 已经失败或者可能会失败,CMS 就认为可能存在碎片导致的,需要进行一次压缩式的 Full GC

    Young GC 为什么会失败一般是因为 Old Gen 没有足够的空间来容纳晋升的对象,比如常见的 “promotion failed”;

    可能失败是通过判断当前 Old Gen 剩余的空间大小是否足够容纳 Young GC 晋升的对象大小。 Young GC 到底要晋升多少是无法提前知道的,因此,这里通过统计平均每次 Young GC 晋升的大小和当前 Young GC 可能晋生的最大大小来进行比较;

  • 触发条件四:是否清理所有 SoftReference。在配置了 CMSCompactWhenClearAllSoftRefs 参数的情况下,会进行一次压缩式的 Full GC

    CMSCompactWhenClearAllSoftRefs 用于控制在 CMS 收集器清理完所有软引用对象后是否触发内存压缩。默认值为 false,即在清理完软引用对象后不会触发内存压缩。

在 GC 调优时应该尽可能的避免压缩式的 Full GC,因为其使用的是 Serial Old GC 类似算法,它是单线程对全堆以及 metaspace 进行回收,STW 的时间会特别长,对业务系统的可用性影响比较大。


http://www.ppmy.cn/news/1519409.html

相关文章

线程池在接受到30个比较耗时的任务时的状态,在前面30个比较耗时的任务还没执行完成的情况下,再来多少个任务会触发拒绝策略?

目录 一、提出问题 二、解答 问题 1: 线程池在接受到30个比较耗时的任务时的状态 问题 2: 在前面30个比较耗时的任务还没执行完成的情况下,再来多少个任务会触发拒绝策略? 总结 一、提出问题 我们首先自定义一个线程池: new ThreadPoo…

python基本语法总结

参考: Python 基础语法 | 菜鸟教程 (runoob.com) Python 语言与 Perl,C 和 Java 等语言有许多相似之处。但是,也存在一些差异。 在本章中我们将来学习 Python 的基础语法,让你快速学会 Python 编程。 第一个Python程序 python编写…

【python】OpenCV—Multi Human Pose Estimation

文章目录 1、背景介绍2、关键点检测模型3、源码与结果4、源码解读——检测关键点5、源码解读——找到有效对6、源码解读——组装个人关键点7、涉及到的库cv2.dnn.blobFromImage 8、参考 1、背景介绍 【python】OpenCV—Single Human Pose Estimation 本文以 COCO 格式为例&am…

内存管理笔记

1、内存管理简介 在计算机系统中,变量、中间数据一般存放在系统存储空间中,只有在实际使用时才将它们从存储空间调入到中央处理器内部进行运算。通常存储空间可以分为两种:内部存储空间和外部存储空间。内部存储空间访问速度比较快&#xff…

中文科技核心

“中文科技核心”通常指的是在中文领域内具有重要影响力和学术价值的科技研究或出版物。这些核心期刊和论文集主要集中在自然科学、工程技术、计算机科学等领域,代表了该领域的前沿研究成果。以下是关于中文科技核心的一些要素和相关内容。 1. 中文科技核心期刊的定…

Transformer参数量和复杂度

在算法岗面试中经常会问到Transformer相关的基础知识。 首先需要清楚Transformer的参数量和复杂度分别在算什么。 定义: 参数量:神经网络中有很多参数矩阵,这个矩阵大小的和就是参数量,静态的,摆在那就在那&#xff…

通过 Filter 改写请求的 Response

通过 Filter 改写请求的 Response 1、自定义 ResponseWrapper 自定义 ResponseWrapper,用于获取 Response Data public class RewriteRespWrapper extends HttpServletResponseWrapper {private final ByteArrayOutputStream output;private ServletOutputStream…

华为 HCIP-Datacom H12-821 题库 (3)

有需要题库的可以看主页置顶 1.运行 OSPF 协议的路由器在交互 DD 报文时,会使用以下哪一个参数选举主从关系? A、接口的 IP 地址 B、接口的 DR 优先级 C、Area ID D、Router ID 答案:D 解析: Router-ID 大的为主,小的…

初爽Stream流

体验Stream流的作用: 需求: 按照下面的要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素 要求: 1.把所有以“张”开头的元素存储到新集合中 2.把“张”开头的,长度为3的元素再存储到新集合中 3.遍历打…

Java小项目IDEA怎么打成jar包

使用IDEA打jar包 在file选项中找 打开jar包所在位置: 将jar包拿出来 直接点击jar包就可以运行

Linux tty模式下无法使用回滚功能解决(shift+pgup方法不管用)

Linux tty模式下无法使用回滚功能解决(shiftpgup方法不管用) 自从内核5.9版本以后,回滚功能就被取消:fbcon: remove soft scrollback code 此前是可以使用 Shift PageUp/PageDown 来滚动的。现在假如我们想查看屏幕以外的文字&…

算法训练营|图论第二天 99.岛屿数量 100.岛屿的最大面积

题目&#xff1a;99.岛屿数量 题目链接&#xff1a; 99. 岛屿数量 (kamacoder.com) 代码&#xff1a; 深度优先搜索&#xff1a; #include<bits/stdc.h> using namespace std; int dir[4][2] { 0,1,1,0,-1,0,0,-1 }; void dfs(vector<vector<int>>&…

MySQL唯一索引大小写敏感性问题及字符集深入解析

1. 问题背景与描述 在实际生产环境中&#xff0c;我们遇到了一个插入重复异常的问题。具体表现在长链接转换为短链接的过程中&#xff0c;生成的短链被插入数据库时触发了唯一索引的冲突错误。错误的根本原因在于数据库使用了不区分大小写的排序规则&#xff0c;导致两个看似不…

Linux下安装MySQL8.0

一、安装 1.下载安装包 先创建一个mysql目录&#xff0c;在将压缩包下载到此 # 下载tar包 wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz等待下载成功 2.解压mysql8.0安装包 tar xvJf mysql-8.0.20-linux-glibc2.12-x86…

尝试用java spring boot+VUE3实现前后端分离部署

前言 这几天开学了&#xff0c;公司这边几个和学校对接的项目都挺忙的&#xff0c;然后我又开始有点闲的情况了。问大佬能不能继续看看若依的项目&#xff0c;大佬让我自己去学了。在看若依的项目的时候在想&#xff0c;python的FLASK后端实现和JAVA spring boot的实现差别大不…

【GPT】Coze使用开放平台接口-【2】创建工作流-语音伪造检测工作流

在Coze使用开放平台接口-【1】创建插件&#xff0c;我们已经成功创建了开放平台的插件&#xff0c;也创建了对应的工具。本文档就根据创建好的插件&#xff0c;来创建对应的工作流&#xff0c;来让接口能够用起来。 下面直接用现成的插件快商通AI开放平台&#xff0c;来创建语音…

深度学习实战1--决策树与随机森林(最新版本不报错)

1.乳腺癌数据集简介 乳腺癌数据集包含了美国威斯康星州记录的569个病人的乳腺癌的病情&#xff0c;包含30个维度的生理指标数据(特征),以及乳腺癌是恶性还是良性的标签。因为这是一个二分类问题&#xff0c; 也叫二类判别数据集。 2.实战任务 这数据主要包含569个样本。每个样…

【3.6】贪心算法-解救生艇问题

一、题目 第 i 个人的体重为 people[i]&#xff0c;每艘船可以承载的最大重量为 limit。 每艘船最多可同时载两人&#xff0c;但条件是这些人的重量之和最多为 limit 。 返回载到每一个人所需的最小船数。(保证每个人都能被船载)。 二、解题思路 题目要求每艘船最多能载两人&…

安美数字酒店宽带运营系统-任意文件读取

漏洞描述&#xff1a; 安美数字酒店宽带运营系统 weather.php 接口存在任意文件读取漏洞&#xff0c;未经身份验证攻击者可通过该漏洞读取系统重要文件&#xff08;如数据库配置文件、系统配置文件&#xff09;、数据库配置文件等等&#xff0c;导致网站处于极度不安全状态 fo…

c++中的匿名对象及内存管理及模版初阶

目录 c中的匿名对象 日期到天数的转换 深入理解析构 深入理解拷贝构造 内存管理 全局变量和static变量的区别&#xff1b; malloc/calloc/realloc的区别 new和delete的意义&#xff1f; operator new与operator delete函数 对比malloc和new operator 定制operator ne…