首页 > 系统相关 >JVM 性能调优 -- 线上应用 JVM 内存调优【实战】

JVM 性能调优 -- 线上应用 JVM 内存调优【实战】

时间:2024-11-22 14:16:15浏览次数:3  
标签:Full Survivor -- 调优 GC 内存 JVM Minor

前言:

上一篇我们分享了线上应用的 JVM 内存预估技巧,通过对 JVM 内存的预估来合理的选用服务器资源和应用部署方案,本篇我们来分享引用的 JVM 调优实例,如何通过 JVM 调优来降低应用的 GC 频率。

JVM 系列文章传送门

初识 JVM(Java 虚拟机)

深入理解 JVM(Java 虚拟机)

一文搞懂 JVM 垃圾回收(JVM GC)

深入理解 JVM 垃圾回收算法

一文搞懂 JVM 垃圾收集器

JVM 调优相关参数

JVM 场景面试题【强烈推荐】

JVM 性能调优 – 线上应用 JVM 内存的的预估设置【实战】

业务案例

假设我们有一个日处理数据过亿的数据计算系统,需要持续不断地从各个数据存储引擎查询数据到 Java 应用中进行归档计算,为了理解简单,我们将案例简单化,数据处理模型大致如下:

在这里插入图片描述

上述的业务模型可以简单理解为一个数据清洗系统,这个数据清洗系统预计每分钟要执行 1000 次数据清洗任务,当然这肯定是一个分布式部署的系统,单落到每个应用上的任务大概是每分钟执行 100 次左右的数据清洗任务。

假设每次清洗任务需要处理 10000 条数据,每次任务的执行需要消耗 10 秒的时间,当前每台服务器的配置是 4C 8G 的配置,分到 JVM 堆的内存是 4.2G,JVM 参数配置是默认配置。

以上就是我们的业务模型,后面我们将根据这个业务模型来完成 JVM 调优。

当前 JVM 堆内存结构分析

上面我们提到了 JVM 参数是默认的参数,因此新生代和老年代分别占有内存为 1.4G 和 2.8G,新生代中 Eden 区域和 Survivor From 和 Survivor To 区域分别占有内存 1.12G 和 0.14G、0.14G,内存占用模型如下:

在这里插入图片描述
以上就是默认的内存占用情况。

当前 JVM 堆的 GC 情况分析

前面我们分析了单个应用上的任务大概是每分钟执行 100 次左右的数据清洗任务,而每次的清洗对象是 10000 条数据,每次的清洗时间是 10 秒,我们假设每条数据的数据占用的内存较大为1KB,那么每次清洗任务需要占用 50000KB,大概是 10MB 的内存,也就是每次执行任务会在 JVM 堆中的 Eden 区域占用 50MB 的内存空间。

因为每分钟要执行 100 次任务,也就是每分钟需要在 Eden 区域占用 1000MB 空间,也就是大概 1G 的空间,而我们的 Eden 区域上面已经分析过了总内存为 1.12GB,加上系统运行中其他边缘业务产生的对象,基本就是 1 分钟就把 Eden 区域的空间占满了,此时就是要进行 Minor GC 了。

Minor GC 过程分析

假设在 1 分钟过后,Eden 区域内存使用完了,再进行下一个数据清洗任务的时候,就会触发 Minor GC。

前面在聊 JVM GC 过程中有提到,Minor GC 的第一步是判断老年代的空间是否大于年轻代的内存,如果不大于则直接触发 Full GC,显然我们这一次 GC 是绝对安全的,因为我们的老年代有 2.8G 的空间。

此次 Minor GC 可以回收多少对象呢?

Minor GC 可以回收多少对象取决于还有多少个任务没有执行完毕,我们假设此时还有 20 个任务没有执行完毕,也就是还有 200 MB 的底对象是不能够回收的,能够回收的是 700MB 的对象,正常来说这 200 MB 对象要去到 Survivor 区域的,但是我们上面分析了,我们的 Survivor 区域只有 0.14GB 也就是 140MB 左右的空间,这 200 MB 的对象显然放不下,此时就会通过空间担保机制, JVM 就会把这 200MB 的对象存放到老年代,这就是这一次 Minor GC 的过程。

一次 Minor GC 会晋升 200MB 的对象到老年代,而前面分析的每分钟都要进行一次 Minor GC,我们的老年代内存空间只有 2.8G,也就是第15 次 Minor GC 的时候老年代空间已经不足了,就会触发 Full GC了。

对象晋升老年代的时候,会先检查老年代可用空间是否大于新生代全部对象?此时老年代可用空间 200MB,新生代对象有 1.14GB,假设当前 Minor GC 过后新生代对象全部存活,老年代是放不下的,那么此时就得看 -XX:-HandlePromotionFailure 参数是否打开了,一般该参数都会打开,此时会进入第二步检查,会看老年代可用空间是否大于历次 Minor GC 过后进入老年代的对象的平均大小,前面已经计算过了,每次 Minor GC 大概会有 200MB 对象会进入老年代,因此到第 15 次 Minor GC 的时候,再通过这个判断过程的时候,发现都不满足,就会触发 Full GC,也就是15 分钟就会触发一次 Full GC,这个 Full GC 的频率十分之高了。

Minor GC 到 Full GC 过程演变如下图:

在这里插入图片描述

对频繁 Full GC 问题进行 JVM 调优

上面我们分析了如果按当前的方式进行运行,系统每 15 分钟就要发生一个 Full GC,这个 Full GC 的频率非常高了,我们知道 Full GC 是非常影响系统性能的,那么我们是否可以降低 Full GC 频率呢?

上面案例快速触发 Full GC 的原因是什么?

根据分析过程不难看出,迅速触发 Full GC 的根本原因是每次进行 Minor GC 的时候根本没有利用到 Survivor 区域,对象直接进入了老年代,那我们 JVM 调优的入口就来了,那就是利用上 Survivor 区域。

如何利用 Survivor 区域?

本案例中利用 Survivor 区域有两种方式,如下

  • 调整 Eden 区域和 Survivor 区域比例,例如比例由默认的 8:1:1 调整为 6:2:2,也就是调整 -XX:SurvivorRatio=8 这个参数,本案例不适用,但也不失为一种 JVM 调优的手段。
  • 调整年轻代和老年代的内存占比,例如由默认的 1:2 调整为 2:2,实际 JVM 调优过程中根据具体场景来进行选择。

本案例我们采用调整 JVM 的年轻代与老年代的内存占比来进行 JVM 调优,我们将默认的 1:2 的比例调整为 1:1。

调整年轻代与老年代的内存占比后,JVM 堆内存分配如下:

在这里插入图片描述

根据当前内存占比,我们的 Survivor From 和 Survivor To 区域分别拥有了大概 210 MB 的内存空间,而且 Eden 区域的内存空间也大于了 1000 MB,这就给 Minor GC 带来了很大的操作空间。

上面的的案例分析之所以最终会导致 15 分钟就发生一次 Full GC 的根本原因是,每次发生 Minor GC 时候产生的 200 MB 对象因 Survivor 区域空间不足而直接晋级到老年代了,现在且不说 Eden 区不会没分钟都发生 Minor GC,就算是发生了 Full GC 产生了 200MB 的对象,这 200MB 的对象也不会直接晋级到 老年代,因此会大大的降低老年代的 Full GC 的频率,如果 Eden、Survivor 区域有足够多的空间,我们可以把对象的晋级的年龄调大一些,甚至理论上来说就不会发生 Full GC 了。

年轻代的空间越大越好吗?

相信懂与不懂的朋友都会回答不是,确实不是年轻代空间越大越好,老祖宗说过物极必反,JVM 也在堆中进行分带设计,进行分代设计必然是有原因的,我们知道 Minor GC 效率高,那 Minor GC 效率为啥高,这里面有一个根本原因就是年轻代的空间也会相对较小(当然也跟年轻代采用的垃圾回收算法等有关系),试想一下,如果年轻代空间足够大,在进行垃圾回收的时候,单单就标记 GC ROOTS 就需要消耗大量时间,最终在进行垃圾回收的时候同样也要消耗大量时间,如此以来跟 Full GC 又有什么区别呢。

总结:本篇从案例入手,分析了系统运行过程中内存占用情况,以及垃圾回收情况的模拟分析,找到了垃圾回收的问题点后,我们针对性的进行年轻代比例适当调整,来减少 Full GC 的发生频率,希望可以帮助到有需要的小伙伴。

如有不正确的地方欢迎各位指出纠正。

标签:Full,Survivor,--,调优,GC,内存,JVM,Minor
From: https://blog.csdn.net/weixin_42118323/article/details/143831764

相关文章

  • IDEA+Docker一键部署项目SpringBoot项目
    文章目录1.部署项目的传统方式2.前置工作3.SSH配置4.连接Docker守护进程5.创建简单的SpringBoot应用程序6.编写Dockerfile文件7.配置远程部署7.1创建配置7.2绑定端口7.3添加执行前要运行的任务8.部署项目9.开放防火墙的11020端口10.访问项目11.可能遇到......
  • 校园圈子论坛二手社团跑腿系统需要多少钱?安装前后端需要多长时间?
    关于校园圈子论坛二手社团跑腿系统的开发费用,这取决于多个因素,包括系统的功能复杂度、开发团队的经验和收费标准、是否需要定制开发等。一般来说,如果系统包含基本的用户注册与登录、二手交易、跑腿服务、论坛交流等功能,并且采用较为成熟的技术框架进行开发,那么费用可能会相对较......
  • Jquery与现代前端框架、库的集成
    目录React与jQuery集成Vue与jQuery集成Angular与jQuery集成在SPA应用中的角色与限制React与jQuery集成在React应用中集成jQuery是一个相对少见的选择,因为React本身提供了强大的虚拟DOM(VDOM)系统来管理UI状态和DOM操作,但某些情况下,利用jQuery的某些成熟功能(如特定的动画效......
  • 你想不到的5个奇葩网站
    互联网的奇妙之处就在于,总有些网站能让你惊掉下巴。以下推荐的五个网站,从娱乐到实用再到纯粹的“无厘头”,绝对能刷新你的认知!1.Pestgame:害虫防治的快乐课堂网址:点击体验害虫防治游戏亮点:这是一个将害虫科普和互动游戏结合的奇特网站。通过了解害虫的种类和习性,你不仅能学......
  • Zepto基本选择器与DOM操作
    目录Zepto基本选择器ZeptoDOM操作Zepto基本选择器基础选择器ID选择器Zepto('#elementId');此代码会选取ID为elementId的DOM元素。类选择器Zepto('.className');选取所有拥有类名为className的元素。标签选择器Zepto('tagName');选取所有指定标签名(如div,s......
  • 免费送源码:Java+django+MySQL django 教师培训反馈系统 计算机毕业设计原创定制
           目   录摘  要IAbstractII第1章  前  言31.1 研究背景31.2 研究现状31.3 系统开发目标3第2章  系统开发环境62.1HTTP协议62.2HTML网页技术62.3B/S结构62.4django脚本语言72.5MySQL数据库72.6Apache简介8第......
  • 小乔陪玩-全链路情绪价值电商平台
    小乔陪玩,一款隶属于红色猎人(四川)信息技术有限公司的创新型全链路情绪价值电商平台。于2024年9月3日正式取得了其标志性的商标“小乔陪玩XiaoQiaoPW”(商标申请号:80717455)。这一里程碑式的进展不仅标志着小乔陪玩在法律层面的正式确立,也预示着其在情绪价值电商领域迈出了坚实的一......
  • Java https validatorException PKIX path building failed 问题处理步骤
    背景这是一个老问题了,其实可以不写,但要花费时间重新整理思绪处理类似的问题很是头疼,因查找的大多数文章只是介绍了其中一部分知识,不能给一个没处理过相关问题的人提供详细步骤,故写此文档。希望大家也能尽可能提供完整的解决方案。原因http升级https时会面临证书校验问题,部......
  • EHOME视频平台EasyCVR萤石设备视频接入平台应急布控球与其他移动监控设备相比有何优势
    在现代视频监控领域,随着技术的进步和应用场景的多样化,对于视频监控设备的要求也越来越高。特别是在紧急情况下,快速部署、高清监控和即时传输的能力变得尤为重要。TSINGSEE青犀视频凭借其在音视频流媒体技术、AI智能技术领域的深入研究,推出了EasyCVR视频汇聚融合平台,该平台以其卓......
  • ABP-VNext 用户权限管理系统实战06---多租户集成
    一、集成1、引用安装包Volo.Abp.AspNetCore.MultiTenancy2、配置租户keyConfigure<AbpAspNetCoreMultiTenancyOptions>(options=>{options.TenantKey="BridgeTenantKey";});3、在代码中写入所有租户,当在也可以在配置文件或数据库中定义你的所有租户Con......