记CMS FGC 的一次调优

这篇具有很好参考价值的文章主要介绍了记CMS FGC 的一次调优。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

介绍

        有一个系统,有如下特征,偶尔会触发 FGC(1小时几次,每次持续4~5分钟):

  1. 机器规格 48C96G,规格已经很大了,不宜再扩大
  2. 内存分配:Young 20GB(1:1:8), Old  70GB, 堆外4GB, 预留 2GB 给 OS
  3. 使用 ParNew GC +  CMS GC
  4. 启动后需要加载大量元数据、缓存,大概占据 30GB~40GB 内存,这些元数据、缓存常驻内存
  5. 业务繁忙,堆内存分配速度很快,低峰期 1GB/s+,高峰期 5GB/s+
  6. 单机大部分时间不会FGC,Old区使用率也符合预期 (比例在30GB~40GB除以70GB);但即将发生FGC时,Old区的利用率是在短时间(2~3分钟以内)猛涨上去的,不是慢慢涨上去的
  7. 在不改代码的情况下,尝试过调整如下 GC 参数,效果不明显或者恶化
    1. 调大 Old、调小 Eden
    2. 使用 G1 GC
    3. 调整 CMS 开始的阈值(从68%改成45%)
  8. 每次执行完 FGC 后 Old 区使用率确实可以降下来,说明没有内存泄露

        我们希望能尽可能减少 FGC 发生频率,GC STW < 5 秒都能接受。

常见 FGC 原因

  1. 有内存泄露
  2. 申请超过容量的堆内存
  3. 碎片化严重 + 大对象
  4. Survivor 太小,YGC 后发生提前晋升,再加上 Old区的垃圾回收速度 < Old区的垃圾产生速度最终导致 FGC

        原因 1 属于代码问题,应该很好看出此类现象,GC 算法无能为力。

        原因 2 属于代码问题,瞬间申请的内存超过了总容量,GC 算法无能为力,可以考虑调低系统的并发度,否则最终系统会由于 OOM 挂掉。

        原因 3 属于 GC 算法问题,一个好的 GC 算法应该要能减轻此类问题,对此程序员不好做些什么改进。

        原因 4 是我们系统本次遇到的原因,下面我展开介绍。

GC提前晋升/过早晋升

        提前晋升是指如下流程的第3步:

  1. Java 执行到分配对象的代码
  2. Eden 区容量不足触发 YGC
  3. YGC 完成之后,Survivor 区容不下在本次 YGC 里存活下来的所有对象,此时部分对象就会提前晋升到 Old 区

提前晋升的危害

        Young 区 和 Old 区的回收算法不同,导致回收速度有很大差异,Old 区的垃圾回收速度是很慢的。如果你的系统里 Old 区的垃圾产生速度 > Old 区的垃圾回收速度,那么就很有可能出现 “concurrent mode failure” 引起 FGC。提前晋升会显著增加 “Old 区的垃圾产生速度”,因此更容易出现 FGC。

对象的声明周期长短

        一般来说我们认为:

  1. 短生命周期对象应该分配到 Young 区,它们一般在几次 YGC 内就必须结束生命。
  2. 长生命周期对象应该进入到 Old 区,这些对象一般是“长期”存在的,比如 static 级别的变量、整个 Spring 的 context 及其引用的 beans、配置过期时间为10分钟的cache等。

        在实际中偶尔会有中生命周期对象出现。

我自创的一些术语,大家能get到含义就行,至于叫法之后可以改改

        主观上它们其实是属于短生命周期对象,但由于各种原因它们撑过了好几次 YGC,最终由于年龄到了或者 Survivor 满了晋升到 Old 区。

        比如在我们的系统里需要经常向外发送 RPC 请求,请求体经 JSON 序列化之后大小几十MB~几百MB都有,为了构造这个请求体本身也需要很多中间对象,它们也是要占据内存的。如果 RPC 发生了超时了,那么这些中间对象不得不等到 RPC 回调执行才会被释放(因为在回调里还用到它们了)。

分析和优化

        我们认为我们系统发生 FGC 的直接原因是,某一时刻发爆发地执行大量 RPC 请求由于 RPC 需要等待较长时间才会报超时异常导致内存无法被及时回收,YGC 频率高(高峰时期大概3~4秒就需要一次 YGC),每个请求消耗的内存多,累加起来已经超过了 Survivor 区(当时我们的 Survivor 区大小才 2GB),导致不停有对象提前晋升到 Old 区,晋升速度超过 Old 区 GC 回收速度,引发 FGC。

        按这个思路,我们的优化是:

  1. 降低系统的并发度:这个优化在FGC之前就已经做了,我们限制最多有 16 个 RPC 请求同时在执行,不宜过低,过低可能就会出现明显的积压了(根据业务需求)
  2. 调大 Survivor 区,Survivor 默认是占 Young 区的 1/(1+1+8)=1/10=10%=2GB,将其调整到 1/(1+1+2)=25%=5GB 之后效果非常好,提前晋升到 Old 区的对象肉眼可见的变少了(可以通过看 Old 区使用量的监控曲线图);事实上我们可以适当将 Old 区的容量更多地划分到 Survivor 上效果会更好。
  3. 在执行 RPC 请求的过程中,将那些不会被引用的变量设置为null;在 callback 里如果要打印 request.size() 的需要将 request.size() 的值提前保存为一个 int 再在回调里引用,避免回调直接依赖 request 变量。

将变量设置为null有利于加速 GC 吗?

        先说结论:至少不会更差,在某些场景下能显著优化GC

        TODO 下面放一些验证代码

        文章来源地址https://www.toymoban.com/news/detail-789160.html

到了这里,关于记CMS FGC 的一次调优的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • hw蓝队初级的一次面试(基础)

    1、失效的访问控制(越权) 2、加密失败 3、注入 4、不安全的设计 5、安全配置错误 6、易受攻击和过时的组件 7、认证和授权失败 8、软件和数据完整性故障 9、安全日志记录和监控失效 10、服务端请求伪造 CSRF:跨站请求攻击(XSRF) 发生条件 :当用户在安全网站A登录后保

    2024年02月01日
    浏览(26)
  • opencv复习(简短的一次印象记录)

    2-高斯与中值滤波_哔哩哔哩_bilibili 1、均值滤波 2、高斯滤波 3、中值滤波 4、腐蚀操作   卷积核不都是255就腐蚀掉 5、膨胀操作 6、开运算 先腐蚀再膨胀 7、闭运算 先膨胀再腐蚀 8、礼帽 原始数据-开运算结果 9、黑帽 闭运算结果-原始数据  10、Sobel算子 左-右,下减上 11、 图

    2024年02月06日
    浏览(30)
  • ChatGPT 生态,毁灭人性的一次开源!

    原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,非公众号转载保留此声明。 很多人可能对百度 文心一言 发布会的现场记忆犹新。几百亿身价的老板,像小学生一样汇报自己的 PPT,充满了忐忑。 其实大可不必,命令行更加富有科技感,也更有说服力。不管对程序员来

    2024年02月02日
    浏览(31)
  • OpenApi接口的一次调用经历(附代码)

    去弄一个api_key:https://platform.openai.com/account/api-keys   先看所有能用的模型: 返回: babbage davinci text-davinci-edit-001 babbage-code-search-code text-similarity-babbage-001 code-davinci-edit-001 text-davinci-001 ada curie-instruct-beta babbage-code-search-text babbage-similarity whisper-1 code-search-babbage-text-001 text-curie-

    2024年02月12日
    浏览(40)
  • edusrc某大学证书的一次漏洞挖掘

    前言 以下涉及到的漏洞已提交至edusrc教育行业漏洞报告平台并已修复,该文章仅用于交流学习,如有不足之处,欢迎各位大佬指点。 正文 1、通过注册一个测试账号然后登录页面 2、在浏览任意功能页面时,发现cookie疑似base64加密 3、通过base64解密网站发现直接解密乱码 ---

    2024年02月05日
    浏览(31)
  • JVM | 基于类加载的一次完全实践

    我在上篇文章:JVM | 类加载是怎么工作的 中为你介绍了Java的类加载器及其工作原理。我们简单回顾下:我用一个易于理解的类比带你逐步理解了类加载的流程和主要角色: 引导类加载器 , 扩展类加载器 和 应用类加载器 。并带你深入了解了这些“建筑工人”如何从底层工

    2024年02月15日
    浏览(68)
  • 记一次简单的SQL调优

    相信大家对后端数据库的 SQL 都不会陌生,但是有时候我们会 无意间 就写出一堆奇怪的SQL, 可能当时还没有发现 ,但是没关系,客户后期会告诉你的,这也没有关系, 只要后期不是你负责解决bug就好 。 可是很不幸有时候这种问题就是分配给你解决 。。。。。。 下面就是我

    2024年02月09日
    浏览(37)
  • 我与 INDCODE AI 创作助手的一次对话

    本文由 大侠(AhcaoZhu)原创,转载请声明。 链接: https://blog.csdn.net/Ahcao2008 本文介绍了 CSDN 嵌入式 INSCODE AI 创作助手 的一次体验,从聊天到编程,五花八门,纯属好玩,不是什么正经测试。 【原创:AhcaoZhu大侠】 没太注意,CSDN创作页面上,啥时候多出一个 创作助手 ,见下图:

    2024年02月07日
    浏览(27)
  • 编译时注解处理器的一次使用经历

    编译时注解处理器在《深入理解Java虚拟机》一书中有一些介绍(前端编译篇有提到),但一直没有机会使用,直到碰到这个需求,觉得再合适不过了,就简单用了一下,这里做个记录。------原文写于2021年2月8日。 我们为公司提供了一套通用的JAVA组件包,组件包内有不同的模

    2024年02月12日
    浏览(31)
  • 对于Ubuntu服务器杀毒的一次记录

    概述:叮咚!您的主机有异常登录地,登录ip来自人类文明的标杆美丽国的加利福尼亚州,请注意排查。可恶的老美啊,又来入侵我华夏主机了,美帝亡我之心不死啊(当然也有可能是境内中国人通过VPN操作境外主机实施的哈),暂且归咎于美帝吧,谁让IP地址是显示的他家的

    2024年02月06日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包