初始JVM参数:
-Xms1536M -Xmx1536M -Xmn512M -Xss256K -XX:SurvivorRatio=6 -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly根据这些参数 , 我们知道大体的内存模型是这样的:最快经过6s之后才会发生一次Young GC 。

文章插图
调优分析示例程序启动后 , 我们调用测试类的test()方法:
@RunWith(SpringRunner.class)@SpringBootTest(classes={Application.class})// 指定启动类public class ApplicationTests { @Bean public RestTemplate restTemplate() {return new RestTemplate(); } @Autowired private RestTemplate restTemplate; @Test public void test() throws Exception {for (int i = 0; i < 10000; i++) {String result = restTemplate.getForObject("http://localhost:8080/user/process", String.class);Thread.sleep(1000);} }}然后观察整个过程前后 , 虚拟机的内存gc变化:

文章插图
发现不仅Young GC次数增多了 , Full GC的次数也随着增多 , 说明对象不仅增长得快 , 连进入老年代的时间挺快的 。
我们回想一下对象进入老年代的几种方式:
- 大对象(代码排除没有大对象)
- 对象到达一定年龄阈值(通过Young GC观察没有达到15次)
- 动态对象年龄判断(Young GC后的存活对象小于Survivor区域的50%)
-Xms1536M -Xmx1536M -Xmn1024M -Xss256K -XX:SurvivorRatio=6 -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=92 -XX:+UseCMSInitiatingOccupancyOnly可以通过jinfo查看JVM参数是否生效 , 优化后的内存模型为:

文章插图
优化后我们再重新跑一下程序 , 新的gc变化:
优化完发现没什么变化 , 反而是Full GC次数还变多了 。

文章插图
我们思考下full gc 比minor gc还多的原因有哪些?
1、元空间不够导致的多余full gc
2、显示调用System.gc()造成多余的full gc , 这种一般线上尽量通过-XX:+DisableExplicitGC参数禁用 , 如果加上了这个JVM启动参数 , 那么代码中调用System.gc()没有任何效果
3、老年代空间分配担保机制
可以简单排除掉前2个原因 , 第三个老年代空间担保机制也可以通过观察minor gc 与full gc的次数比例进行排除 , 那接下来就可能真的就是程序产生了很多占内存的对象 。我们可以通过jmap、jvisualvm来跟踪到占内存的对象 。
jmap -histo 27808

文章插图
查到了有大量User对象生成 , 这个可能是问题所在 , 但不确定 , 还必须找到对应的代码确认 , 如何找到对应的代码有如下几种方式:
1、代码里全文搜索生成User对象的地方(适合只有少数几处地方的情况)
2、如果生成User对象的地方太多 , 无法定位具体代码 , 我们可以同时分析下占用cpu较高的线程 , 一般有大量对象不断产生 , 对应的方法代码肯定会被频繁调用 , 占用的cpu必然较高 , 参考上一篇https://www.cnblogs.com/process-h/p/16879018.html
经验总结扩展阅读
- 441010怎么算24点
- MySQL数据库的性能分析 ---图书《软件性能测试分析与调优实践之路》-手稿节选
- JVM调优工具使用手册
- JVM运行时数据区域详解
- JVM学习笔记——内存模型篇
- 星之彼端最强阵容搭配思路参考攻略
- jvm双亲委派机制详解
- 万字详解JVM,让你一文吃透
- JVM学习笔记——类加载和字节码技术篇
- 航海王热血航线欢乐海钓玩法思路是什么