前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【生产案例面试题】JVM调优

【生产案例面试题】JVM调优

作者头像
CBeann
发布2024-05-26 14:01:24
600
发布2024-05-26 14:01:24
举报
文章被收录于专栏:CBeann的博客

写作目的

最近上线了一个需求,遇到了一个JVM报警的问题,很荣幸能遇到,在此分享一下整个调优的过程。

背景

我们是中台服务,我们的甲方就是上游不同的业务。中台原则上是业务和能力分离,但是不可避免的是分不开,所以我们通过SPI的机制让上游的业务实现SPI接口从而执行他们自己的逻辑。本次需求我们上线了一个大需求,要同时发布很多业务方实现的SPI包。我们是灰度发布,发布一台机器后发现频繁的FGC导致监控报警。

补充一下我们的机器规格是4核4G内存和80G磁盘。GC垃圾收集器是CMS和ParNew。

接下来开始进行推理和论证。

推断堆空间有问题

频繁的FGC初步想法就是OOM,比如静态集合无限添加对象。但是去机器上找了一下OOM的Dump文件这个是没找到的,所以说只能手动dump。

代码语言:javascript
复制
jmap -dump:format=b,file=/tmp/myapp_dump.bin pid1234

使用MAT去分析,去找自己的类最多的,发现并没有找到那种一枝独秀特别多的。下面是反例,公司不方便截图

因为是灰度,所以我们有正常的机器。对比有问题机器和没问题机器新生代和老年带的变化趋势、速成和使用大小,整体是相似的,这块就不符合常理了。类似下面的图

结论:新生代老年代和正常机器一样,初步推断堆空间正常。

推断元空间有问题

如果不是堆空间引起的FGC,那就是元空间要满了。接着通过arthas的dashboard命令对比,这里发现这个值新老机器差距很大

那就需要调大元空间

代码语言:javascript
复制
把
-XX:MetaspaceSize=1500m
-XX:MaxMetaspaceSize=1500mm
修改为
-XX:MetaspaceSize=2048m
-XX:MaxMetaspaceSize=2048m

此时机器再发布后就不会出现FGC了。

结论:元空间小,导致频繁FGC

元空间到底为什么变大

通过JVM的命令,可以看出来加载了哪些类

代码语言:javascript
复制
 jcmd 28818 GC.class_histogram

那我看上图有什么意义呢? 对比新老机器,可以获得两份加载的类 通过awk命令能洗出来有哪些类,然后通过diff命令就可以看出来不同的类。

通过分析两个加载的类不同,发现两个问题。

  1. 本次加载的类有本次需求新上的,符合预期。
  2. 里面有很多MethodAccessor,看我的另一篇文章

总结

  • 如果面试回答,你可以说你引入了很多pom,这种场景其实是很常见的。
  • 本文对回答的关键词都做了加深,包括每一步的命令是什么,且能能量化的都用数字表示(比如机器大小)
  • 调大元空间意味着别的会缩小,所以最终方法是充钱,扩大机器的配置。

课外补充

补充一下有意义的jvm启动参数

代码语言:javascript
复制
-XX:ParallelGCThreads=4 (并行收集,几核机器设置几核)
-Xms6g   (调优,设置新生代初始大小)
-Xmx6g   (调优,设置新生代最大值)
-Xmn2g   (调优,设置堆空间大小)
-XX:MetaspaceSize=2048m
-XX:MaxMetaspaceSize=2048m
-XX:MaxDirectMemorySize=1g
-XX:SurvivorRatio=8   (新老年代默认8:1:1)
-XX:+UseConcMarkSweepGC  (使用CMS垃圾收集器)
-XX:CMSMaxAbortablePrecleanTime=5000 (并发标记阶段之后、重新标记阶段之前,就让你执行这么长时间)
-XX:+CMSClassUnloadingEnabled (允许类卸载,比如线上使用内存诊断工具Arthas,用完后会有残留)
-XX:CMSInitiatingOccupancyFraction=80 (老年带到达80%,触发老年代收集)
-XX:+UseCMSInitiatingOccupancyOnly(配合上面参数使用)
-XX:+ExplicitGCInvokesConcurrent (针对System.gc()触发老年带的GC,否则就是fullGC)
-Xloggc:/home/admin/logs/gc.log  (GC日志目录)
-XX:+PrintGCDetails  (GC日志详细细节)
-XX:+PrintGCDateStamps(每个垃圾收集事件发生的确切日期和时间戳)
-XX:+HeapDumpOnOutOfMemoryError  (OOM)
-XX:HeapDumpPath=/home/admin/logs/java.hprof (OOM)

参考

有过JVM调优经验吗【面试题】

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写作目的
  • 背景
  • 推断堆空间有问题
  • 推断元空间有问题
  • 元空间到底为什么变大
  • 总结
  • 课外补充
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档