问题现象回顾

春节放了十来天假,开始上班没过几天,就收到生产环境CPU报警的消息,看了一下zabbix最近30天的CPU监控曲线,发现就最近两天CPU明显飙升,曲线如图:

再看了一下skywalking监控,发现负载确实都很高,看来是真的。仔细看了一下监控的指标,发现了一个异常情况:FGC次数远超过YoungGC次数,监控如下图:

对比分析

首先一个正常的服务中是很少会出现FGC次数远超过YoungGC次数这种现象的,我们又对比了一下其他环境的没报警的服务器,这个服务启动了才两天,发现YoungGC是比FGC多很多,FGC一个都没有,如下图:

原因推测分析

一个服务出现大量FGC肯定会导致服务无响应、CPU飙升,所以我们推测是FGC太频繁导致的,那么就先把堆内存dump出来,打开MAT分析一下看看

这里已经可以看到存活对象最大的占比异常了,最大的一类对象关联内存占用了1.9G,仔细分析Dominator Tree,发现如下

继续展开这个占比最高的,找到最底层对象是谁,发现全都是这个ClassPathList对象

再继续展开ClassPathList对象看到底是哪里生成的

终于找到我们自己的代码了,就是这个LogAspect类生成了大量的ClassPathList对象导致的,找到生成对象的地方,原来是这里生成ClassCLassPath对象后,ClassPool会再生成他引用的ClassPathList对象

那么这里就有一个问题,为什么生成的ClassPathList对象不会被YoungGC,最后进入到老年代导致大量的FGC呢?

要回答这个问题,需要看看ClassPool和ClassPathList的内部实现机制:

首先来看ClassPool,他的实现是一个单例模式,使用ClassPool.getDefault()方法获取,这是系统所有请求入参对象的Class容器池,所以ClassPool是不会被YoungGC回收的

其次ClassPool内部持有一个ClassPoolTail变量的引用,所以只要ClassPool没有被YoungGC回收,那么ClassPoolTail也不会被YoungGC回收

再次看ClassPoolTail对象,内部就持有了ClassPathList对象的引用了,按照前面两步逻辑,那么这个ClassPoolTail内部的这一个ClassPathList对象也不会被YoungGC回收(如下图)。至此是否已经清晰了?还没有,因为ClassPoolTail也只会产生一个对象,所以也只有一个ClassPathList对象的引用,那么为什么还会有那么多的ClassPathList对象呢?答案藏在最后

最后来看这个ClassPathList对象内部实现,可以看到ClassPathList内部是一个自定义的链表实现的,每一个对象都持有下一个ClassPathList对象的引用,所以只要后面还有ClassPathList对象,都会被无穷的引用下去,至此ClassPathList不会被YoungGC回收的真相大白了,超过默认15次YoungGC后被送进了老年代,最后由FGC来回收,但是频繁FGC就会导致CPU报警,这就是问题所在

最后的疑问

那么为什么其他prod环境没有出现这个问题,偏偏是pre环境出现了呢?只是因为过了一个春节?

其实prod一样也会出现,只不过机器的内存配置高一点,服务启动参数加了FGC的执行限制,因此还没有达到触发FGC的条件

-XX:CMSInitiatingOccupancyFraction=70

如果再过一个月,prod肯定也会出现CPU报警的问题

java zero fill_一次JavaAssist引发的生产环境CPU报警的问题相关推荐

  1. 【开发经验】java服务生产环境CPU使用过高解决思路

    文章目录 思路 1.定位java服务进程 2.定位线程id 3.定位代码块 java服务生产环境CPU突然升高,日志查询无果时,可以通过使用jvm的调试工具定位问题. 思路 定位java服务进程--& ...

  2. java开发的微信公众号服务端生产环境中的两个大坑

    摘要: 我们开发的公众号,由于将功能开发完毕后,未对服务进行压力测试,因此用到的组件中的参数值全是默认的,服务上线后一段时间运行得倒没什么问题,随着服务得访问量增加,一些多线程并发的问题就逐步暴露出来 ...

  3. docker java 中文乱码_java使用awt包在生产环境docker部署时出现中文乱码的处理

    描述: 有一个业务是需要后台生成图片,后台使用了Graphics2D类.在docker部署时,图片上的中文变成方块. 解决方案: 百度了一下,发现是生产上的docker容器下没有中文字体,需要在容器里 ...

  4. Java生产环境下性能监控与调优详解 大纲 学习感悟

    Java生产环境下性能监控与调优详解 生产环境发生了内存溢出如何处理? 生产环境应该给服务器分配多少内存合适? 如何对垃圾收集器的性能进行调优? 4.生产环境CPU负载飙高该如何处理? 5.生产环境应 ...

  5. Java 17.0.2 LTS 生产环境免费使用版本下载地址

    Java 17 LTS 是 Java SE 平台的最新长期支持版本.根据Oracle 免费条款和条件许可,JDK 17 二进制文件可在生产环境中免费使用,并可免费重新分发.自Java 8u202版本后 ...

  6. 【Jedis testOnBorrow配置 引发的生产事故】

    [Jedis testOnBorrow配置 引发的生产事故] 背景 问题排查 问题总结 原因分析 破案 总结 完 背景 公司系统在昨晚升级之后,一晚上基本没睡觉的我一大早7点被运维打电话叫醒,并告诉了 ...

  7. 【深入理解java虚拟机v3 】 4.2.6 jstack:Java堆栈跟踪工具(查看所有的线程信息占cpu最高的进程和线程)

    文章目录 1. 原文概述 补充概述 2. 例子 2.1 用jstack加进程id查找死锁 2.2 jstack统计线程数 2.3 jstack检测cpu高 3. 实战 3.1 一次cpu高的实战记录 ...

  8. 生产环境下JAVA进程高CPU占用故障排查

    感谢原作者 http://blog.chinaunix.net/uid-10449864-id-3463151.html 问题描述: 生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常 ...

  9. 使用idea对生产环境的JAVA应用进行远程调试

    有时候明明测试环境没问题,部署到生产环境却有bug,于是想直接点生产环境打断点走到本地代码. JAVA自身支持调试功能,并提供了一个简单的调试工具--JDB,类似于功能强大的GDB,JDB也是一个字符 ...

最新文章

  1. ACMNO.12有一分数序列: 2/1 3/2 5/3 8/5 13/8 21/13...... 求出这个数列的前N项之和,保留两位小数。 输入 N 输出 数列前N项和 样例输入 10
  2. linux正则表达式sed
  3. 利用GitHub搭建博客自定义域名失效问题解决方法
  4. Asp.Net生命周期的详解
  5. mysql 主从复制介绍_MySQL 主从复制介绍
  6. Hadoop数据传输工具sqoop - 样例
  7. mappedBy的作用
  8. mysql创建表代码_MySQL------代码建表
  9. mybatis获取map中的key和value
  10. 全国独一份!200万杭州人公积金可用支付宝刷脸提取,秒到账!
  11. 个人简历模板 个人简历表下载 个人简历模板下载
  12. HTML学生个人网站作业设计:动漫网站设计——悬崖上的金鱼姬(5页) HTML+CSS 简单DIV布局网页模板代码
  13. 计算机更换内存条后无法连接网络,换主机后怎么连接网络
  14. 《开天辟地》之《网上冲浪篇》将带你进入一个精彩的互联网世界
  15. 18W快充4000毫安电量 魅族魅蓝Note5续航实测
  16. swfobject.js 2.2 使用方法
  17. 似然函数、最大似然估计简单理解
  18. 【词汇】BOSS系统
  19. 商汤公开IPO上市,估值1026亿,创始人汤晓鸥教授身家220亿
  20. 李建忠讲23种设计模式笔记-上

热门文章

  1. 苹果系统itunes连iphone连不上服务器,itunes无法连接iphone的解决方法
  2. 112358序列c语言,112358(112358的规律是什么)
  3. CPU不同字母的意思
  4. SRE从踩坑到牛逼(二)利用Python进行Arcgis站点分析+Nginx日志分析
  5. 2021年中国企业风险投资发展现状及未来发展趋势分析[图]
  6. spring boot 2.1.7启动过程源码解析
  7. MFC中Combo的使用
  8. Frontiers in Pharmacology2020 | MOSES+:分子生成模型的benchmark平台
  9. Flutter之开屏广告缓存本地方案(无插件版),兼容 IOS、安卓
  10. java 热键_定义自己的热键