点击↑上方↑蓝色“编了个程”关注我~

这是Yasin的第 45 篇原创文章

Y说

今天上午被阿里罚款的消息刷屏了。这个事情也发酵很长一段时间了,今天算是尘埃落定吧。听说因为这事股价蒸发了一千亿美金。。。

很快官方就发表了《致客户和公众的一封信》,态度可以说是非常“认真”且“正确”了。

对我等升斗小民来说,这事应该影响不大。我们能做的,就是把自己的工作尽力做好,少写点bug~

当然,也希望公司越来越好,国家和社会也越来越好。

先推荐一篇好文

最近写了几篇关于GC的文章,主要是因为线上有一些关于GC的问题,所以想顺便总结一波,梳理一下GC的一些知识点和排查思路。

之前有读者留言说能不能写一篇实战经验方面的,这不就来了吗~

我们项目上用到的主要还是CMS + ParNew的组合。所以重点看的资料也是这方面的。

在学习的过程中,也拜读了美团技术团队的这篇文章《Java中9种常见的CMS GC问题分析与解决》。这篇文章质量非常高,从理论知识,源码分析,到常见的GC问题案例,囊括了分析路径、根因、调优策略等等内容,非常详尽且全面,尤其是最后部分的处理流程SOP和根因鱼骨图,非常nice。「墙裂推荐,值得一读」!!!

知道大家喜欢现成的,所以我手动copy了这两张图过来,有需要的自取:

^排查问题SOP^

^根因鱼骨图^

GC问题案例

我遇到的案例可能没有上面文章作者那么丰富,但也是真实遇到的几个案例,所以借这篇文章分享出来,大家可以参考参考,避免踩类似的坑。

案例1 Young GC频繁

之前有个任务会频繁地重复调用一个接口。所以用guava cache做了一个简单的内存缓存。结果上线后发现经常收到Young GC频繁的告警,时间跟这个任务的启动时间也比较吻合。

通过监控看到的GC图大概是这样:

^案例1^

可以看到,Young GC的次数会在某一个时间点飙升。同时伴随着Old区域内存快速升高,最后会触发一次Full GC。

根据这个情况,可以肯定的是由于本次代码改动引起的。通过Heap Dump分析后发现,占用内存较大的是一个guava cache的Map对象。

查找代码发现,使用guava cache的时候,没有设置最大缓存数量和弱引用,而是设置了一个几分钟的过期时间。而这个任务的量又比较大,到线上后很快就缓存了大量的对象,导致频繁触发Young GC,但又由于有引用GC不掉(这个从Survivor区的内存大小图像可以推测),所以慢慢代数比较多的对象就晋升到了老年代,后面老年代内存到达一定阈值引发Full GC。

后面通过设置最大缓存数量解决了这个问题。又积累了一个宝贵的经验,完美!

案例2 Young GC和Old GC都频繁

在线上灰度环境中发现收到Young GC和Old GC频繁的告警。监控看到的GC图大概长这样:

^案例2^

根据GC图大概可以看出来,Young GC和Old GC都非常频繁,且每次都能回收走大量的对象。那可以简单地推测:确实是产生了大量的对象,且极有可能有一部分大对象。小对象引发的Young GC频繁,而大对象引发了Old GC频繁。

排查下来也是一段代码引起的。对于一个查询和排序分页的SQL,同时这个SQL需要join多张表,在分库分表下,直接调用SQL性能很差,甚至超时。于是想了个比较low的办法:查单表,把所有数据查出来,在内存排序分页。用了一个List来保存数据,而有些数据量大,造成了这个现象。用Heap Dump分析,也印证了这个猜测,List类型的对象占用了大量的空间。

案例3 接口线程池满和Full GC

这是一个报接口线程池满的问题。但每次都会在同一时间Full GC。监控图大概长这样:

^案例3^

从时间上来看,先是Java线程数量飙升,然后触发Full GC。后面重启后,Java线程数量恢复正常水位。

这里涉及到一个冷知识:一个Java线程默认会占用多少内存?

->

这个参数可以控制:-XX:ThreadStackSize。在64 位的Linux下, 默认是1 MB(这个说法也不全对,还是取决于栈深度)。Java 11对这个有一个优化,可以减少内存占用。详情可以参考这篇文章:https://dzone.com/articles/how-much-memory-does-a-java-thread-take

<-

排查下来根因是这个应用还是使用的Log4j 1,而Log4j 1有性能问题,在高并发下,下面这段代码的同步块可能会引起大量线程阻塞:

void callAppenders(LoggingEvent event) {int writes = 0;for(Category c = this; c != null; c=c.parent) {// Protected against simultaneous call to addAppender, removeAppender,...synchronized(c) {if(c.aai != null) {writes += c.aai.appendLoopOnAppenders(event);}if(!c.additive) {break;}}}if(writes == 0) {repository.emitNoAppenderWarning(this);}
}

解决办法就是减少日志打印,升级日志框架到Log4j 2或者Logback。

案例4 应用启动时Full GC频繁

这个是较早的一个案例了,GC图已经找不到了。

但引发Full GC频繁的大概就这几种可能性:

  • 调用System.gc()

  • Old区空间不足

  • 永久代/元空间满

根据代码和GC图排除了前面两种可能性,那就是元空间满了。在Java 8中,XX:MaxMetaspaceSize是没有上限的,最大容量与机器的内存有关;但是XX:MetaspaceSize是有一个默认值的:21M。而如果应用需要进元空间的对象较多(比如有大量代码),就会频繁触发Full GC。解决办法是可以通过JVM参数指定元空间大小:-XX:MetaspaceSize=128M

总结

可以看到上面的大多数案例都是代码改动或者应用框架引起的。一般公司内都会有默认的一套JVM参数,真正需要JVM参数调优解决问题的case其实是比较少的。

而且有时候GC问题可能并不是问题的根源,有可能是其它问题引发的GC问题,在实际排查的时候要根据日志及时间线去判断。

至于怎么去判断是否“频繁”和“耗时长”?虽然有一些公式计算,但我觉得只要不影响现有的业务,那就是可以接受的。而如果某个应用的GC表现明显不同于以往的平均水平,或者其它相似应用的水平,那就有理由怀疑是不是存在GC问题了。

很多时候GC问题不充分的压测是测试不出来的,而压测成本又比较大。经常会在线上灰度发布中观察到,所以需要在灰度发布的时候密切观察系统的监控和告警。如果有条件,可以上红蓝部署,降低风险。

GC问题还是蛮复杂的,需要大量的经验和理论知识。遇到之后可以总结分析一下根因,平时也可以看看其他人的博客,吸取经验,这样就能不断完善自己的知识体系。

关于作者

我是Yasin,一个爱写博客的技术人

微信公众号:编了个程(blgcheng)

个人网站:https://yasinshaw.com

欢迎关注这个公众号

往期推荐

盘点Java中的那些常用的Garbage Collector

排查GC问题常用的工具

你们要的线上GC问题案例来啦相关推荐

  1. 概要设计说明书案例_逆向前行,趁势而为外贸学院线上教学优秀案例展(七)...

    学生居家学习,教师远程授课.在这种情况下,如何调动学生的学习积极性提升线上教学质量?如何实现班级教学管理的实效性?信息工程系谢粤芳老师在<Android 项目开发>课程教学中,基于&quo ...

  2. 由对称性知定点一定在x轴上_线上优秀教学案例(九)|计算机科学与工程学院刘钊:“延期不延教”之“1+X课堂”...

    [编者按]受新冠肺炎疫情影响,按照教育部和河北省教育厅统一部署,学校延迟春季开学时间.为最大程度减少疫情和延期开学对我校教育教学工作的影响,本学期,我校以线上教学的形式拉开序幕.面对新的教学模式,各学 ...

  3. 计算机网络教学优秀教案,线上教学优秀案例:计算机网络基础公开课

    线上教学优秀案例:计算机网络基础公开课 教师姓名:赵志城 姓名:赵志城 毕业院校:天津职业技术师范大学 所学专业:计算机科学与技术 学历:本科 所教专业:计算机 教育理念:细节见精神,习惯成命运. 教 ...

  4. matlab数字图像处理大作业_线上教学优秀案例(16) | 数字图像处理基于蓝墨云+企业微信的线上教学经验分享...

    [前言]目前我校在线课堂教学如火如荼,老师们在各大教学平台化身"直播高手""网课达人"倾心打造精彩课堂,有效保证了在线学习与线下课堂教学质量实质等效.为进一步推 ...

  5. hive on spark 线上问题排查案例分享

    来源:明哥的IT笔记  编辑:数据社 全文共 2320个字,建议阅读 10 分钟 大家好,今天看到明哥分享一个某业务系统的线上 hive on spark 作业在高并发下频现作业失败问题的原因分析和解 ...

  6. 线上 CPU100% 异常案例:一个正则表达式引发的血案

    前几天线上一个项目监控信息突然报告异常,上到机器上后查看相关资源的使用情况,发现 CPU 利用率将近 100%.通过 Java 自带的线程 Dump 工具,我们导出了出问题的堆栈信息. 我们可以看到所 ...

  7. 线上展厅空间感案例 广交会布展

    如何在展览设计中创造最理想的空间感? 展览设计,说容易,说难,想用法兰克福展览设计创造最理想的空间感,这需要做很多事情,比如实现展览设计,必须做几个方面.看看如何创造最理想的空间感? 1.布展空间 即 ...

  8. jvm排查线上gc问题步骤

    1. 清楚从程序角度,有哪些原因导致FGC? 大对象:系统一次性加载了过多数据到内存中(比如SQL查询未做分页),导致大对象进入了老年代. 内存泄漏:频繁创建了大量对象,但是无法被回收(比如IO对象使 ...

  9. grep线上环境精典案例后续

    请执行命令取出 linux 中 eth0 的 IP 地址(请用 cut,有能力者也可分别用 awk,sed 命令答). 自己的方法: [root@nginx_back ~]# ifconfig eth ...

最新文章

  1. leetcode--Reverse Integer
  2. 站立会议报告(12)
  3. python编码转换语句_好程序员Python教程之字符串编码知识小结
  4. 程序员懂点经济学-股票投资
  5. 遍历 Dictionary,你会几种方式?
  6. http1.X与2.0
  7. 图解TCP三次握手和四次挥手!(简单易懂)
  8. JS判断文本框中只能输入数字和小数点
  9. Java web (JSP)入门
  10. spring整合ehcache
  11. 少讲大道理,多解决小问题
  12. Adobe 软件清理工具AdobeCreativeCloudCleanerTool.exe
  13. java正则表达式大全(手机号、身份证、地址、姓名、邮箱、银行卡等...)
  14. windows控制台命令: 快捷键大集合
  15. 八位一体共阳极数码管显示电子时钟+闹铃+温度检测
  16. v-inline-date,类似携程,飞猪,带价格的时间选择
  17. 有效的括号(leetcode 20)
  18. LeetCode - OrderMap - 715.Range模块
  19. 【蓝桥杯java真题】:和尚挑水
  20. 第四章 专业统计(上)-统计实务

热门文章

  1. 分布式相关问题总结(精选)
  2. 通过深度神经网络和树搜索掌握围棋游戏
  3. 【224】基本功能计算器
  4. 如何使用 SAP Intelligent Robotic Process Automation 自动操作 Excel
  5. 官方盘点 .NET 7 新功能
  6. 网红营销新矩阵 || 小微网红KOL+KOC才是流量增长爆发点
  7. 复现 Oriented R-CNN RTX3080ti
  8. Xz1 android p更新,索尼XZ1/XZP港版正式推送Android 9.0更新
  9. R语言爬虫豆瓣高评分电影(喝最烈的酒,熬最深的夜,吃最好的胃药,敷最贵的面膜)
  10. 谷歌、互联网股票与以太坊