写作目的
JVM其实比较偏理论的,日常工作中很少遇到。但是面试他问,所以需要自己mock一下场景进行准备这个问题的回复。
本次分析的场景的元空间太小导致频繁FGC的问题。
源码&启动参数
gitee下载源码
启动-调优前
nohup java -XX:MetaspaceSize=60m -XX:MaxMetaspaceSize=60m -XX:+UseConcMarkSweepGC -Xmx2g -Xms2g -XX:+PrintGCDetails -jar springboot-demo-0.0.1-SNAPSHOT.jar &
启动-调优后
nohup java -XX:MetaspaceSize=160m -XX:MaxMetaspaceSize=160m -XX:+UseConcMarkSweepGC -Xmx2g -Xms2g -XX:+PrintGCDetails -jar springboot-demo-0.0.1-SNAPSHOT.jar &
复现步骤
- 首先在服务器上使用 调优前 的脚本启动jar
- 查看java的进程ID,然后查看进程的GC情况
- 在服务器上输入 curl localhost:8080/demo2 ,然后就会出现上图中的红框中的变化,即出现了FGC
回答面试题-通过生产案例说明进行调优
表象:为什么需要调优
我的生产环境是JDK8版本,垃圾收集器使用的是ParNew和CMS收集器。
当时是上线的一个大版本,其中包含了很多类,每一个类有很多属性。
在灰度发布的时候发现新的机器出现了频繁的FGC报警。之前FGC是一星期都不会有一次,现在是5秒一次,这种是很反常的。对代码进行重新review后发现逻辑没问题,所以可以判断是需要调优的。
过程:使用了什么命令表现了什么数据
从理论上可以知道出现FGC是老年带或者元空间满导致的,首先要判断老年代还是元空间导致的FGC。
首先通过jstat -gc命令查看了GC的情况及各个带的情况。发现老年带和元空间都是没满,但是实际上元空间是满(不是到100%才GC,这有一个阈值,可百度)的。
我们初步定位到元空间导致FGC的原因。那我们就可以通过参数把元空间调大
-XX:MetaspaceSize=999m -XX:MaxMetaspaceSize=999m
然后重新发布后发现确实没FGC了,一切正常
分析:为什么会出现GC以及知识点
理论:讲道理
简单贴一下demo的代码。类多且属性多(mock的类TestModel 有700个属性),通过反射调用16次
int size = 700;
Class<?> clazzTestModel = Class.forName("com.example.gcdemo.gcc.TestModel");
TestModel testModel = new TestModel();
for (int i = 0; i < size; i++) {
//jni调用转为本地调用
int inflationThreshold = 16;
for (int i1 = 0; i1 < inflationThreshold; i1++) {
Method method = clazzTestModel.getMethod("setField" + i, String.class);
method.invoke(testModel, String.valueOf(i));
}
}
看一下反射invoke到底是做的什么操作。直接跟进到下面的方法
反射的底层就是调用的NativeMethodAccessorImpl方法的invoke方法。如果调用次数超过15次,则会走if方法。
而这个generate方法就会生成一个Class文件(怎么能证明是Class文件:百度Class文件的结构,然后看这坨generate代码)。
一个方法反射15次就会生成一个Class文件,我很多类很多方法自然就会生成很多Class类,把元空间撑爆了。
实践:看元空间有啥
发现了下面的一堆,和理论一致
![在这里插入图片描述](https://img-blog.csdnimg.cn/53ac1b41574c4a00afbf026a8ae931c0.png
继续秀:我还关注到了年轻代GC
我还关注了年轻代GC且加机器解决。重点表达不需要调整,能通过机器(钱)解决就是小问题。
当然也发现年轻代的GC也会频繁一些,原来是5秒一次年轻代GC,现在4秒左右,其实也合理。因为增加了一个业务线,流量变大,new的对象自然变多了。所以年轻代的GC不需要调整。
后面是通过加机器把这个年轻代的GC又变回的原来的样子。
命令整理
- 查看java进程的gc情况
jstat -gc pid9527 1000
- 查看元空间的内容
jcmd pid9537 GC.class_histogram
- Arthas
贼贼贼好用 https://arthas.aliyun.com/doc/
参考
面试官:如何进行 JVM 调优(附真实案例)【转载】