性能文章>JVM实战:优化我的IDEA GC>

JVM实战:优化我的IDEA GC原创

3年前
951217

IDEA是个好东西,可以说是地球上最好的Java开发工具,但是偶尔也会卡顿,仔细想想IDEA也是Java开发的,会不会和GC有关,于是就有了接下来对IDEA的GC进行调优

IDEA默认JVM参数:
-Xms128m
-Xmx750m
-XX:MaxPermSize=350m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50

第一次优化
以默认参数启动完成后,利用jstat -gcutil pid 3s 查看GC情况:

image.png
这张图反映出了1个非常明显的问题:Old区会扩容。这是因为Xms和Xmx值不一致引起的;所以对JVM参数的第一个优化点就是Xms和Xmx这两个参数;
第一次优化后的JVM参数为(说明:笔者的电脑是8G,如果你的电脑配置更高,可以适当调大这三个参数):
-Xms1024m
-Xmx1024m
-Xmn372m

-XX:MaxPermSize=350m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50

第二次优化
经过第一次优化后,再次启动IDEA,得到如下的GC日志:
image.png
很明显:Metaspace会出现扩容的情况,所以第二次优化点为:-XX:MetaspaceSize和-XX:MaxMetaspaceSize。

第二次优化后的JVM参数为:
-Xms1024m
-Xmx1024m
-Xmn372m
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=256m

-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50

说明:由于我用的是JDK8,所以删除了参数-XX:MaxPermSize=350m,取而代之的是-XX:MetaspaceSize=256m和-XX:MaxMetaspaceSize=256m,如果读者你用的是JDK7及以前的版本,那么请用-XX:PermSize=256m和-XX:MaxPermSize=256m

总结
经过第二次优化后,启动IDEA的GC情况如下:
image.png
由图所示, GC情况比较健康了,没有FGC,且GCT有明显的下降,唯一的缺陷就是YGC的平均耗时过长,这是由于我的电脑配置较低,CPU是双核心的缘故,一般生产环境Linux服务器上YGC的时间是10毫秒级别,如果你的Java实例YGC时间几十毫秒甚至超过100ms就要注意排查,可能有比较严重的问题了;

写在最后
加上几个经验参数,最终的JVM参数如下:
-Xms1024m
-Xmx1024m
-Xmn372m
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=256m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:+CMSScavengeBeforeRemark
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=2

-XX:SoftRefLRUPolicyMSPerMB=50

说明:

-XX:+UseParNewGC:显示声明Young区垃圾回收算法,也可以不显示声明(显示声明为了让JVM参数更易懂),因为Old区申明为CMS GC的话,Young区默认就是ParNew;

-XX:+CMSParallelRemarkEnabled:CMS的remark阶段多线程并行;该参数默认就是true,所以这里只是显示声明;

-XX:+CMSScavengeBeforeRemark:CMS GC前执行一次Minor GC,即YGC;

-XX:CMSInitiatingOccupancyFraction=75:如果Old区声明为CMS GC的话,该参数的默认值为92,比较大,建议调小到75,减少Promotion failed的概率;

-XX:+UseCMSInitiatingOccupancyOnly:只有当Old区达到75%时才触发CMS GC,如果不声明的话,还有很多种其他条件触发CMS GC;

-XX:+UseCMSCompactAtFullCollection:CMS是标记清理算法,每次回收后有内存碎片问题,该参数会整理内存碎片,但是会影响暂停时间;

-XX:CMSFullGCsBeforeCompaction=2:表示经过多少次foreground CMS GC后对Old区做一次压缩。由于UseCMSCompactAtFullCollection这个参数为true整理内存碎片时会影响性能,但是碎片问题也需要解决或者缓解。所以,设置适当调整该参数的值,在执行多次foreground CMS GC后才对Old区进行压缩;

再用笔者在文章《一个神奇的网站perfma:一站式解决所有JVM疑难杂症》中介绍的“参数检查”,将最后要配置的JVM参数粘贴上去进行检查,检查结果如下,几乎完美
image.png
需要说明的是,经过perfma检查后,perfma给出了一些建议,如下所示。由图可知,perfma建议额外增加的参数主要是与GC日志相关的参数,由于笔者这次是对IDEA进行优化,所以这些参数并不需要添加。如果你验证的Java服务端的JVM参数,那么这些参数是强烈建议添加的(这件事情告诉我们,具体问题还得具体分析):
image.png

点赞收藏
分类:标签:
阿飞Javaer
请先登录,查看1条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

【全网首发】一次想不到的 Bootstrap 类加载器带来的 Native 内存泄露分析

【全网首发】一次想不到的 Bootstrap 类加载器带来的 Native 内存泄露分析

记一次线上RPC超时故障排查及后续GC调优思路

记一次线上RPC超时故障排查及后续GC调优思路

解读JVM级别本地缓存Caffeine青出于蓝的要诀 —— 缘何会更强、如何去上手

解读JVM级别本地缓存Caffeine青出于蓝的要诀 —— 缘何会更强、如何去上手

【全网首发】一次疑似 JVM Native 内存泄露的问题分析

【全网首发】一次疑似 JVM Native 内存泄露的问题分析

解读JVM级别本地缓存Caffeine青出于蓝的要诀2 —— 弄清楚Caffeine的同步、异步回源方式

解读JVM级别本地缓存Caffeine青出于蓝的要诀2 —— 弄清楚Caffeine的同步、异步回源方式

【全网首发】从源码角度分析一次诡异的类被加载问题

【全网首发】从源码角度分析一次诡异的类被加载问题

7
1