点击关注公众号,Java干货及时送达

通过这一个多月的努力,将FullGC从40次/天优化到近10天才触发一次,而且YoungGC的时间也减少了一半以上,这么大的优化,有必要记录一下中间的调优过程。

对于JVM垃圾回收,之前一直都是处于理论阶段,就知道新生代,老年代的晋升关系,这些知识仅够应付面试使用的。前一段时间,线上服务器的FullGC非常频繁,平均一天40多次,而且隔几天就有服务器自动重启了,这表明的服务器的状态已经非常不正常了,得到这么好的机会,当然要主动请求进行调优了。未调优前的服务器GC数据,FullGC非常频繁。

首先服务器的配置非常一般(2核4G),总共4台服务器集群。每台服务器的FullGC次数和时间基本差不多。其中JVM几个核心的启动参数为:

-Xms1000M -Xmx1800M -Xmn350M -Xss300K -XX:+DisableExplicitGC -XX:SurvivorRatio=4 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC
  • -Xmx1800M:设置JVM最大可用内存为1800M。

  • -Xms1000m:设置JVM初始化内存为1000m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

  • -Xmn350M:设置年轻代大小为350M。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。

  • -Xss300K:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

第一次优化

一看参数,马上觉得新生代为什么这么小,这么小的话怎么提高吞吐量,而且会导致YoungGC的频繁触发,如上如的新生代收集就耗时830s。初始化堆内存没有和最大堆内存一致,查阅了各种资料都是推荐这两个值设置一样的,可以防止在每次GC后进行内存重新分配。基于前面的知识,于是进行了第一次的线上调优:提升新生代大小,将初始化堆内存设置为最大内存

-Xmn350M -> -Xmn800M
-XX:SurvivorRatio=4 -> -XX:SurvivorRatio=8
-Xms1000m ->-Xms1800m

将SurvivorRatio修改为8的本意是想让垃圾在新生代时尽可能的多被回收掉。就这样将配置部署到线上两台服务器(prod,prod2另外两台不变方便对比)上后,运行了5天后,观察GC结果,YoungGC减少了一半以上的次数,时间减少了400s,但是FullGC的平均次数增加了41次。YoungGC基本符合预期设想,但是这个FullGC就完全不行了。

就这样第一次优化宣告失败。

第二次优化

在优化的过程中,我们的主管发现了有个对象T在内存中有一万多个实例,而且这些实例占据了将近20M的内存。于是根据这个bean对象的使用,在项目中找到了原因:匿名内部类引用导致的,伪代码如下:

public void doSmthing(T t){redis.addListener(new Listener(){public void onTimeout(){if(t.success()){//执行操作}}});
}

由于listener在回调后不会进行释放,而且回调是个超时的操作,当某个事件超过了设定的时间(1分钟)后才会进行回调,这样就导致了T这个对象始终无法回收,所以内存中会存在这么多对象实例。

通过上述的例子发现了存在内存泄漏后,首先对程序中的error log文件进行排查,首先先解决掉所有的error事件。然后再次发布后,GC操作还是基本不变,虽然解决了一点内存泄漏问题,但是可以说明没有解决根本原因,服务器还是继续莫名的重启。

内存泄漏调查

经过了第一次的调优后发现内存泄漏的问题,于是大家都开始将进行内存泄漏的调查,首先排查代码,不过这种效率是蛮低的,基本没发现问题。于是在线上不是很繁忙的时候继续进行dump内存,终于抓到了一个大对象

这个对象竟然有4W多个,而且都是清一色的ByteArrowRow对象,可以确认这些数据是数据库查询或者插入时产生的了。于是又进行一轮代码分析,在代码分析的过程中,通过运维的同事发现了在一天的某个时候入口流量翻了好几倍,竟然高达83MB/s,经过一番确认,目前完全没有这么大的业务量,而且也不存在文件上传的功能。咨询了阿里云客服也说明完全是正常的流量,可以排除攻击的可能。

就在我还在调查入口流量的问题时,另外一个同事找到了根本的原因,原来是在某个条件下,会查询表中所有未处理的指定数据,但是由于查询的时候where条件中少加了模块这个条件,导致查询出的数量达40多万条,而且通过log查看当时的请求和数据,可以判断这个逻辑确实是已经执行了的,dump出的内存中只有4W多个对象,这个是因为dump时候刚好查询出了这么多个,剩下的还在传输中导致的。而且这也能非常好的解释了为什么服务器会自动重启的原因。

解决了这个问题后,线上服务器运行完全正常了,使用未调优前的参数,运行了3天左右FullGC只有5次

第二次调优

内存泄漏的问题已经解决了,剩下的就可以继续调优了,经过查看GC log,发现前三次GullGC时,老年代占据的内存还不足30%,却发生了FullGC。于是进行各种资料的调查,在https://blog.csdn.net/zjwstz/article/details/77478054 博客中非常清晰明了的说明metaspace导致FullGC的情况,服务器默认的metaspace是21M,在GC log中看到了最大的时候metaspace占据了200M左右,于是进行如下调优,以下分别为prod1和prod2的修改参数,prod3,prod4保持不变

-Xmn350M -> -Xmn800M
-Xms1000M ->1800M
-XX:MetaspaceSize=200M
-XX:CMSInitiatingOccupancyFraction=75

-Xmn350M -> -Xmn600M
-Xms1000M ->1800M
-XX:MetaspaceSize=200M
-XX:CMSInitiatingOccupancyFraction=75

prod1和2只是新生代大小不一样而已,其他的都一致。到线上运行了10天左右,进行对比:prod1:

prod2:

prod3:

prod4:

对比来说,1,2两台服务器FullGC远远低于3,4两台,而且1,2两台服务器的YounGC对比3,4也减少了一半左右,而且第一台服务器效率更为明显,除了YoungGC次数减少,而且吞吐量比多运行了一天的3,4两台的都要多(通过线程启动数量),说明prod1的吞吐量提升尤为明显。通过GC的次数和GC的时间,本次优化宣告成功,且prod1的配置更优,极大提升了服务器的吞吐量和降低了GC一半以上的时间。

prod1中的唯一一次FullGC:

通过GC log上也没看出原因,老年代在cms remark的时候只占据了660M左右,这个应该还不到触发FullGC的条件,而且通过前几次的YoungGC调查,也排除了晋升了大内存对象的可能,通过metaspace的大小,也没有达到GC的条件。这个还需要继续调查,有知道的欢迎指出下,这里先行谢过了。

总结

通过这一个多月的调优总结出以下几点:

  • FullGC一天超过一次肯定就不正常了

  • 发现FullGC频繁的时候优先调查内存泄漏问题

  • 内存泄漏解决后,jvm可以调优的空间就比较少了,作为学习还可以,否则不要投入太多的时间

  • 如果发现CPU持续偏高,排除代码问题后可以找运维咨询下阿里云客服,这次调查过程中就发现CPU 100%是由于服务器问题导致的,进行服务器迁移后就正常了。

  • 数据查询的时候也是算作服务器的入口流量的,如果访问业务没有这么大量,而且没有攻击的问题的话可以往数据库方面调查

  • 有必要时常关注服务器的GC,可以及早发现问题

来源 | https://blog.csdn.net/cml_blog/article/details/81057966

热门内容:面试官问:MySQL 的自增 ID 用完了,怎么办?
王者荣耀中一个英雄是怎么被产生的?
饿了么CTO:“不能被烂用的框架不是好框架”!
最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡

一个多月的努力,FGC发生频率优化了400倍相关推荐

  1. 晒晒一个多月的seo小成就

    在自己的一个多月的努力之下,自己的做的一个seo网站:都江堰seo 目前基本上已经稳定下来了.哈哈,晒晒自己的小小的成就吧. 百度收录: 搜索引擎收录: 关键词排名: 我清楚我现在做的还远远不够,但是 ...

  2. 时隔一个多月发布原生一体化云安全产品,ZStack的发展还可以更快

    前不久,ZStack和大河云联共同发布"全球首个混合云+SDN专线一体化"产品时,我曾写下过这样一句话:"ZStack这一年的成长,真是快."后来记得还和ZSt ...

  3. 微软Live Mail包含重大Bug,可导致用户无法登录,我已经一个多月无法登录自己的邮箱了。...

    微软Live Mail包含重大Bug,可导致用户无法登录,我已经一个多月无法登录自己的邮箱了. 我是微软Live Mail 的试用用户,自从上个月十几号开始,我的邮箱就无法登陆了. 当时的错误信息是: ...

  4. 神武3手游一直等待服务器响应,神武3手游:新区人太多遭“抱怨”,玩家一个多月时间攒出神兽!...

    原标题:神武3手游:新区人太多遭"抱怨",玩家一个多月时间攒出神兽! 在昨天的<神武3手游>中,新门派"曜华城"的上线让很多的游戏玩家纷纷踏上了新门 ...

  5. 入职一个多月了,谈谈感想

    好久没写博客了,入职已经有一个多月了,今天我谈谈我工作的感想吧. 昨天一个同事离职了,跟我一样是出来实习的,工作经验比我多,思维很活跃,离职原因很简单:想从事底层开发.人各有志吧,跟我相同的是大学都不 ...

  6. mysql内存不断被占用,导致每隔一个多月就自动重启,修改数据库配置后,问题解决...

    这个月初,通过zabbix监控发现有1台mysql数据库的从库内存剩余空间不断降低.检查以往的监控历史图表,发现由于内存占用不断增大,每隔一个多月,就会因为内存严重不足,导致这台服务器的1个mysql ...

  7. 如果表不存在则创建_当创建一个文件的时候,操作系统发生了什么

    操作文件是我们平时经常有的操作.但是我们可能并不是很了解他们原理,比如为什么删除一个很大的文件,会非常快?创建一个文件的时候,系统发生了什么?为什么删除的文件,还可以恢复?知其然知其所以然.我们一起深 ...

  8. lm_license_file 冲突怎么办_【微课+语音】孩子一个多月没有上学了怎么办?

    点击上面"和谐园"关注我们! 孩子一个多月没有上学了怎么办? 课程日期:2020年11月4日 岳老师:大家晚上好!现在开始上课.今晚我们帮助新家长,由飞逝先帮助,大家欢迎. 和谐园 ...

  9. 一个男网友娶到一个女网友后在洞房发生的事情

    一个男网友娶到一个女网友后在洞房发生的事情 先说明:我是转过来给大家看的. 一名男网友如愿以偿地娶到了一位美丽的女网友. 新婚之夜的洞房里,他们深情款款地替对方宽衣解带. 新郎说:"咱们既然 ...

最新文章

  1. C++/C++11中std::queue的使用
  2. 环境监控告警系统之TIM即时消息推送部署
  3. Scala 语言转义字符
  4. javascript变量提升/函数提升
  5. VueJS实现用户管理系统
  6. JavaWeb之Cookie与Session
  7. 嵌入式工具——strace
  8. centos7 防火墙_【Linux简单实用小命令001】CentOS 7、8的防火墙端口开放
  9. 解决Appium-windows安装时无法自动下载Appium-Desktop
  10. python全栈测试开发工程师_Python测试开发全栈核心课程 互联网测试工程师必修课...
  11. 阿里云服务器的登录方法
  12. 连共享打印机问题汇总
  13. TC358860XBG EDP/DP TO DAUL MIPI DSI
  14. 惊闻母校徐兵老师英年早逝
  15. Android 定制自己的launcher
  16. SAS小白入门第二节:SAS数据类型和格式化(输入和输出)
  17. 去掉文件夹最大化时豪杰V8的播放按钮
  18. Tietze扩张定理
  19. 程序媛女友考公务员秒杀互联网!
  20. 【小知识】12个月份用英语表示

热门文章

  1. php中echo单引号双引号及大括号的作用
  2. ngZorro 级联菜单选择任意一项 关闭菜单
  3. 点击空白区域关闭软键盘
  4. Vue项目打包部署教程及常见错误-前端开发
  5. android n进入分屏代码分析_平板电脑全面进入多任务时代,Android N原生支持分屏显示...
  6. AD如何使用3D功能《通用快捷键》
  7. ps制作logo标志设计视频教程和LOGO设计思路分享
  8. linux7如何删除用户,如何在CentOS 7上添加和删除用户
  9. OpenGL--材质
  10. PR 2019 快速入门(16)