某系统反馈『性能抖动,响应时间会突然飙高,TP999 MAX会到3000+』,初步怀疑是JVM FULL GC导致的 STW,观察FULL GC日志默认的JVM参数:

-Xms4096m -Xmx4096m -XX:PermSize=512M -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=1024M -XX:+UseCodeCacheFlushing

从线上down下来的GC LOG如下:

1768.617: [GC [PSYoungGen: 1313280K->31072K(1341440K)] 3990240K->2729238K(4137984K), 0.0992420 secs] [Times: user=0.36 sys=0.01, real=0.10 secs]
1770.525: [GC [PSYoungGen: 1316704K->27632K(1345536K)] 4014870K->2750306K(4142080K), 0.0552640 secs] [Times: user=0.20 sys=0.00, real=0.06 secs]
1772.437: [GC [PSYoungGen: 1319408K->51424K(1343488K)] 4042082K->2795338K(4140032K), 0.0578170 secs] [Times: user=0.23 sys=0.00, real=0.06 secs]
1774.583: [GC [PSYoungGen: 1343200K->30912K(1340416K)] 4087114K->2796362K(4136960K), 0.0746000 secs] [Times: user=0.27 sys=0.00, real=0.07 secs]
1776.521: [GC [PSYoungGen: 1316535K->27328K(1341952K)] 4081986K->2817152K(4138496K), 0.0792640 secs] [Times: user=0.26 sys=0.01, real=0.08 secs]
1776.601: [Full GC [PSYoungGen: 27328K->0K(1341952K)] [ParOldGen: 2789824K->150473K(2796544K)] 2817152K->150473K(4138496K)
[PSPermGen: 60521K->60480K(524288K)], 0.5549000 secs] [Times: user=1.64 sys=0.00, real=0.55 secs]
1779.045: [GC [PSYoungGen: 1285632K->51105K(1334784K)] 1436105K->201578K(4131328K), 0.0313710 secs] [Times: user=0.12 sys=0.00, real=0.03 secs]
1781.122: [GC [PSYoungGen: 1330593K->30368K(1338880K)] 1481066K->202953K(4135424K), 0.0522210 secs] [Times: user=0.17 sys=0.00, real=0.05 secs]
1782.995: [GC [PSYoungGen: 1309856K->27488K(1341440K)] 1482441K->223926K(4137984K), 0.0416840 secs] [Times: user=0.13 sys=0.01, real=0.04 secs]
.
.
.
2007.041: [GC [PSYoungGen: 1328928K->27808K(1351168K)] 4059412K->2783016K(4147712K), 0.0694050 secs] [Times: user=0.24 sys=0.00, real=0.07 secs]
2008.972: [GC [PSYoungGen: 1330848K->47079K(1350144K)] 4086056K->2827611K(4146688K), 0.0648990 secs] [Times: user=0.23 sys=0.00, real=0.07 secs]
2009.037: [Full GC [PSYoungGen: 47079K->0K(1350144K)] [ParOldGen: 2780532K->191662K(2796544K)] 2827611K->191662K(4146688K)
[PSPermGen: 60530K->60530K(524288K)], 3.4921610 secs] [Times: user=13.39 sys=0.08, real=3.49 secs]
2014.630: [GC [PSYoungGen: 1303040K->31712K(1328640K)] 1494702K->223374K(4125184K), 0.0672680 secs] [Times: user=0.21 sys=0.00, real=0.07 secs]
2016.521: [GC [PSYoungGen: 1312223K->27136K(1339392K)] 1503886K->243740K(4135936K), 0.0297230 secs] [Times: user=0.09 sys=0.00, real=0.03 secs]
2018.442: [GC [PSYoungGen: 1307632K->47901K(1335296K)] 1524236K->285700K(4131840K), 0.0524640 secs] [Times: user=0.18 sys=0.00, real=0.05 secs]
2020.530: [GC [PSYoungGen: 1325341K->30272K(1337856K)] 1563140K->289717K(4134400K), 0.0615270 secs] [Times: user=0.22 sys=0.00, real=0.06 secs]

分析上述日志,可以看出两个问题:

1. 每次ygc,晋升至老年代的对象体积较大,平均为20m+,这导致fgc频率较高;

2. FGC的时间很长,上面看到的是550ms,实际上还有2000+的,这导致FGC开销很大;

因而调优思路很明确:

1. 减少每次ygc晋升大小;

2. 尽可能的减少每次fgc的时间开销;

因而进行了如下的尝试:

一. 使用parallel scavenge GC,但是加入如下参数 :

-Xmn1350m -XX:-UseAdaptiveSizePolicy  -XX:SurvivorRatio=6
         调优思路:
               ygc每次晋升到old gen的内容较多,而这很可能是因为JVM 动态的调整eden 和 survivor区,导致它们空间过小,部分本该在new gen呆着的对象直接跳到old gen

了(此现象在survivor区较为明显,因为其本来就较小)

调优效果:

可以看到调优后full gc频率大为减少(由4min一次--->变为30h一次),同时因为少了 频繁调整new gen的开销,ygc耗时也略微减少了.

遗留问题:

虽然fgc频率大为降低,但是每次fgc的耗时还是一样,500ms+~2000ms

二. 改用传说中的 CMS GC,加入jvm参数如下(原来的配置不变):

-XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+UseCMSInitiatingOccupancyOnly
       -XX:CMSInitiatingOccupancyFraction=70
      调优思路:
           使用CMS GC,启用碎片整理,降低fgc的耗时

调优效果:

遗留问题:

91832.693: [GC [1 CMS-initial-mark: 1968357K(2811904K)] 2123963K(4021504K), 0.0732300 secs] [Times: user=0.06 sys=0.01, real=0.08 secs]
91832.767: [CMS-concurrent-mark-start]
91834.022: [CMS-concurrent-mark: 1.256/1.256 secs] [Times: user=4.06 sys=0.94, real=1.25 secs]
91834.022: [CMS-concurrent-preclean-start]
91834.040: [GC91834.040: [ParNew: 1091621K->50311K(1209600K), 0.0469420 secs] 3059979K->2018697K(4021504K), 0.0473540 secs] [Times: user=0.16 sys=0.01, real=0.05 secs]
91834.123: [CMS-concurrent-preclean: 0.051/0.101 secs] [Times: user=0.31 sys=0.05, real=0.10 secs]
91834.123: [CMS-concurrent-abortable-preclean-start]
91834.900: [CMS-concurrent-abortable-preclean: 0.769/0.777 secs] [Times: user=2.36 sys=0.53, real=0.78 secs]
91834.903: [GC[YG occupancy: 595674 K (1209600 K)]91834.904: [Rescan (parallel) , 0.6762340 secs]
91835.580: [weak refs processing, 0.0728400 secs]91835.653: [scrub string table, 0.0009380 secs]
[1 CMS-remark: 1968386K(2811904K)] 2564060K(4021504K), 0.7555510 secs] [Times: user=2.73 sys=0.03, real=0.76 secs]
91835.659: [CMS-concurrent-sweep-start]
91836.401: [GC91836.401: [ParNew: 1087111K->47187K(1209600K), 0.0723650 secs] 2884822K->1844924K(4021504K), 0.0727230 secs] [Times: user=0.26 sys=0.00, real=0.07 secs]
91837.799: [GC91837.800: [ParNew: 1083987K->45402K(1209600K), 0.0663740 secs] 2609145K->1570570K(4021504K), 0.0667940 secs] [Times: user=0.23 sys=0.01, real=0.07 secs]
91839.374: [GC91839.374: [ParNew: 1082202K->45240K(1209600K), 0.0673220 secs] 2353716K->1316904K(4021504K), 0.0677680 secs] [Times: user=0.23 sys=0.00, real=0.07 secs]
91840.710: [GC91840.710: [ParNew: 1082040K->19453K(1209600K), 0.0215620 secs] 2188694K->1126165K(4021504K), 0.0219340 secs] [Times: user=0.06 sys=0.01, real=0.02 secs]
91842.338: [GC91842.338: [ParNew: 1056253K->52429K(1209600K), 0.0507020 secs] 1780994K->777227K(4021504K), 0.0511040 secs] [Times: user=0.19 sys=0.00, real=0.05 secs]
91843.636: [GC91843.636: [ParNew: 1089229K->21084K(1209600K), 0.0408210 secs] 1657456K->589323K(4021504K), 0.0412140 secs] [Times: user=0.13 sys=0.00, real=0.05 secs]
91845.222: [GC91845.223: [ParNew: 1057884K->42762K(1209600K), 0.0419470 secs] 1315163K->300052K(4021504K), 0.0423230 secs] [Times: user=0.13 sys=0.00, real=0.04 secs]
91845.925: [CMS-concurrent-sweep: 9.875/10.266 secs] [Times: user=31.77 sys=6.94, real=10.26 secs]
91845.936: [CMS-concurrent-reset-start]
91845.985: [CMS-concurrent-reset: 0.049/0.049 secs] [Times: user=0.16 sys=0.03, real=0.05 secs]

oldgen gc开销还是较大,虽然比ps gc略好,而且通过gc日志发现,主要耗时都是在remark的rescan阶段

三. 降低remark的时间开销,加入参数:-XX:+CMSScavengeBeforeRemark

调优思路:

通常情况下进行remark会先对new gen进行一次扫描,而且这个开销占比挺大,所以加上这个参数,在remark之前强制进行一次ygc

调优效果:

直接看日志吧,从下面日志看到remark的时间缩短的了很多。

 91718.963: [GC [ CMS-initial-mark: 1968409K(2811904K)] 2019966K(4021504K), 0.0419650 secs] [Times: user=0.02 sys=0.01, real=0.04 secs]
91719.005: [CMS-concurrent-mark-start]
91720.142: [CMS-concurrent-mark: 1.137/1.137 secs] [Times: user=3.72 sys=0.83, real=1.14 secs]
91720.142: [CMS-concurrent-preclean-start]
91720.183: [CMS-concurrent-preclean: 0.041/0.041 secs] [Times: user=0.13 sys=0.03, real=0.04 secs]
91720.183: [CMS-concurrent-abortable-preclean-start]
91720.525: [GC 91720.525: [ParNew: 1074573K->72397K(1209600K), 0.0613610 secs] 3042982K->2040991K(4021504K), 0.0617860 secs]
[Times: user=0.23 sys=0.00, real=0.06 secs]
91721.314: [CMS-concurrent-abortable-preclean: 1.063/1.131 secs] [Times: user=3.59 sys=0.82, real=1.13 secs]
91721.316: [GC[YG occupancy: K ( K)][GC2017--25T19::47.124+: 91721.317: [ParNew: 657780K->30915K(1209600K), 0.1393790 secs]
2626374K->1999535K(4021504K), 0.1398100 secs] [Times: user=0.52 sys=0.00, real=0.14 secs]
91721.456: [Rescan (parallel) , 0.0302040 secs]91721.487: [weak refs processing, 0.0691870 secs]
91721.556: [scrub string table, 0.0009370 secs] [ CMS-remark: 1968619K(2811904K)] 1999535K(4021504K), 0.2452990 secs] [Times: user=0.72 sys=0.00, real=0.25 secs]
91721.562: [CMS-concurrent-sweep-start][CMS-concurrent-sweep: 8.561/8.898 secs] [Times: user=27.82 sys=5.98, real=8.89 secs]
[CMS-concurrent-reset-start]

至此,jvm调优告一段落,目前线上大约30H生一次 CMS GC(“FGC”),每次耗时在300ms以内,算是比较完美了。

JVM参数如下:

-Xms4096m -Xmx4096m -XX:PermSize=256M -XX:MaxPermSize=256M -XX:ReservedCodeCacheSize=1024M -XX:+UseCodeCacheFlushing

-Xmn1350m -XX:-UseAdaptiveSizePolicy  -XX:SurvivorRatio=6 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+UseCMSInitiatingOccupancyOnly     -XX:CMSInitiatingOccupancyFraction=70  -XX:+CMSScavengeBeforeRemark

JVM调优之---一次GC调优实战的更多相关文章

  1. JVM系列(四)之GC调优

    JVM内存参数调优 为什么要GC调优? 或者说的更确切一些,对于基于Java的服务,是否有必要优化GC?应该说,对于所有的基于Java的服务,并不总是需要进行GC优化,但当你的系统时常报了内存溢出或者 ...

  2. JVM 配置常用参数和常用 GC 调优策略

    链接:https://juejin.im/post/5c94a123f265da610916081f   JVM 配置常用参数 堆参数 回收器参数 如上表所示,目前主要有串行.并行和并发三种,对于大内 ...

  3. Java GC 专家系列3:GC调优实践

    本篇是”GC专家系列“的第三篇.在第一篇理解Java垃圾回收中我们学习了几种不同的GC算法的处理过程,GC的工作方式,新生代与老年代的区别.所以,你应该已经了解了JDK 7中的5种GC类型,以及每种G ...

  4. 管中窥豹——从对象的生命周期梳理JVM内存结构、GC调优、类加载、AOP编程及性能监控

    如题,本文的宗旨既是透过对象的生命周期,来梳理JVM内存结构及GC相关知识,并辅以AOP及双亲委派机制原理,学习不仅仅是海绵式的吸收学习,还需要自己去分析why,加深对技术的理解和认知,祝大家早日走上 ...

  5. 深入JVM系列(二)之GC机制、收集器与GC调优

    一.回想JVM内存分配 须要了解很多其它内存模式与内存分配的,请看 深入JVM系列(一)之内存模型与内存分配 1.1.内存分配: 1.对象优先在EDEN分配 2.大对象直接进入老年代  3.长期存活的 ...

  6. JVM GC调优一则--增大Eden Space提高性能

    版权声明:本文为横云断岭原创文章,未经博主同意不得转载.微信公众号:横云断岭的专栏 https://blog.csdn.net/hengyunabc/article/details/24924843 ...

  7. 深入JVM系列(二)之GC机制、收集器与GC调优(转)

    一.回顾JVM内存分配   需要了解更多内存模式与内存分配的,请看 深入JVM系列(一)之内存模型与内存分配 1.1.内存分配: 1.对象优先在EDEN分配2.大对象直接进入老年代 3.长期存活的对象 ...

  8. JVM GC调优一则–增大Eden Space提高性能

    缘起 线上有Tomcat升级到7.0.52版,然后有应用的JVM FullGC变频繁,在高峰期socket连接数,Cpu使用率都暴增. 思路 思路是Tomcat本身的代码应该是没有问题的,有问题的可能 ...

  9. GC参考手册 —— GC 调优(基础篇)

    GC调优(Tuning Garbage Collection)和其他性能调优是同样的原理.初学者可能会被 200 多个 GC参数弄得一头雾水, 然后随便调整几个来试试结果,又或者修改几行代码来测试.其 ...

随机推荐

  1. CentOS7 vsftp使用ftp客户端登录时不同的用户进入到不同的文件夹方法

    anonymous_enable=NO local_enable=YES write_enable=YES local_umask=777 #anon_upload_enable=YES #anon_ ...

  2. 用Beautiful Soup解析html源码

    #xiaodeng #python3 #用Beautiful Soup解析html源码 html_doc = """ <html> <head> ...

  3. Ubuntu16.04 Arduino UNO R3开发板

    使用的是国内改过的版本, usb芯片换成了ch341, 晶振不是原版的16MHz而是12MHz, 杜邦线孔布局和原版一致. 设备连接 在Ubuntu16.04下不需要驱动, 能直接认出ch341设备 ...

  4. ISO七层协议

    1 OSI参考模型 谈到网络不能不谈OSI参考模型,虽然OSI参考模型的实际应用意义不是很大,但其的确对于理解网络协议内部的运作很有帮助,也为我们学习网络协议提供了一个很好的参考.在现实网络世界里,T ...

  5. DLL中不能调用CoInitialize和CoInitializeEx

    在项目中为了用API访问Wmi Object来实现命令wmic的功能,所以得使用COM库,使用COM库之前得初始化一些东西. m_hr = CoInitializeEx(, COINIT_APARTM ...

  6. jquery.uploadify 在firefox会出现httperror

    原来是因为我的上传处理页面的page 继承了一个基类影响到的 然后这个基类 好像是因为在别的项目里面的原因 希望对也遇到这样的问题的人有帮助咯

  7. ASP.NET 动态查找数据 并且生成xml文档 同时使用xslt转换为xhtml

    前言 xsl是一门标签解析语言,很适合做动态网页的前台标签 www.bamn.cn 1 首先是aspx页面 添加一个输入框 按钮 还有一个用来显示解析后的xhtml代码的控件 <form id= ...

  8. Ubuntu登录Windows Server 2008r2 密码总是错误与NLA验证

    日期:2013-05-22   经过一天的折腾,终于能够用Ubuntu登录Windows server 2008 R2 了. 寝室里面用小本子,装的ubuntu,实验室的服务器是win server0 ...

  9. 【RS】Stochastic PCA with ℓ2 and ℓ1 Regularization - ℓ2 和 ℓ1正则的随机 PCA

    [论文标题] Stochastic PCA with ℓ2 and ℓ1 Regularization   (ICML 2018) [论文作者]—Poorya Mianjy  (Johns Hopki ...

  10. iOS配置SSO授权

    禁止/激活SSO授权 用于控制平台是否使用SSO方式进行授权(目前只支持新浪微博.Facebook.QQ空间.腾讯微博.人人网.Pocket.默认情况下是激活SSO授权方式.),代码如下: //激活S ...