提供服务的网站,企业网络方案设计思路,建网站花钱吗,动画制作软件有哪些?项目报 OutOfMemoryError、GC overhead limit exceeded 问题排查以及解决思路实战
前言#xff1a; 问题现象描述#xff1a; 1#xff0c;生产环境有个定时任务#xff0c;没有初始化告警数据【告警数据量为1000多个】 2#xff0c;其他定时任务执行正常 3#xff0c;查…项目报 OutOfMemoryError、GC overhead limit exceeded 问题排查以及解决思路实战
前言 问题现象描述 1生产环境有个定时任务没有初始化告警数据【告警数据量为1000多个】 2其他定时任务执行正常 3查询日志到定时任务执行之前有日志打印 4手动触发补偿告警定时任务接口报OutOfMemoryError GC overhead limit exceeded也会报
1、现象问题排查
1.1 程序是否触发判断
1首先定时任务之前可以正常初始化告警指标数据说明程序可以正常执行不会存在问题【初次判断】
1.2 JVM内存大小查看
2会不会是内存不够用导致的结果使用arthas工具查看内存使用情况 输入memory 返回如下信息
1其中堆空间eden_space 区内存总共462M已使用310M 2还剩下大概 150M左右【大概够用只是猜想】
1.3 手动触发定时任务查看内存使用情况
1现象是eden_space 很快达到99%并且报GC overhead limit exceeded
1.4 查看定时任务代码逻辑发现创建大量对象大概1000多个对象【在一瞬间】代码大概如下。
1为啥是1000多个对象是因为有1000多个告警要在凌晨触发定时任务生成告警指标数据 2告警的数据是kafka接收的kafka监听到数据实时拉取数据批量保存到数据库 3告警有4大类每个类有12个类别
未优化前逻辑
private final int batchSize 500;
public void initKafkaAlarmInventoryTask() {// 待批量保存清单数据ListTaskAlarmInventoryEntity batchInsertTaskInventoryList new ArrayList();// 1.获取需要初始化的告警数据 // TODO: 从数据库查询 ListInitAlarmTaskInventoryEntity initTaskInventoryEntities .....// initInspectionSystemMap key:为告警的类型【12大类型】 v:每个类型下面的指标集合initInspectionSystemMap.forEach((k, v) - {// 对每个指标进行遍历v.forEach(x - {// 相关业务逻辑 如果当前的告警数据已经消费到就跳过否则就保存消息batchInsertTaskInventoryList.add(....);}});});if (CollectionUtils.isNotEmpty(batchInsertTaskInventoryList)) {for (int i 0; i batchInsertTaskInventoryList.size(); i batchSize) {int endIndex Math.min(i batchSize, batchInsertTaskInventoryList.size());// TODO保存到数据库}}}}优化后
private final int batchSize 500;
public void initKafkaAlarmInventoryTask() {// 待批量保存清单数据ListTaskAlarmInventoryEntity batchInsertTaskInventoryList new ArrayList();// 1.获取需要初始化的告警数据 // TODO: 从数据库查询 ListInitAlarmTaskInventoryEntity initTaskInventoryEntities .....// initInspectionSystemMap key:为告警的类型【12大类型】 v:每个类型下面的指标集合initInspectionSystemMap.forEach((k, v) - {// 对每个指标进行遍历v.forEach(x - {// 相关业务逻辑 如果当前的告警数据已经消费到就跳过否则就保存消息batchInsertTaskInventoryList.add(....);}});if (CollectionUtils.isNotEmpty(batchInsertTaskInventoryList)) {for (int i 0; i batchInsertTaskInventoryList.size(); i batchSize) {int endIndex Math.min(i batchSize, batchInsertTaskInventoryList.size());// TODO保存到数据库}}}});}4可能是一次性初始化1000多个对象把堆内存使用完导致的这个问题优化成根据告警指标类型分类 分成几百个类初始化打包重新调用后还是同样问题报错【本地执行没有问题】
1.5 使用arthas 跟踪接口执行情况
使用trace命令查看每个方法的调用时间以及调用情况
[arthas13362]$ trace com.xxx.xx.xx.kafka.KafkaAlarmReportConsumerClient initKafkaAlarmInventoryTask命令大概意思是 arthas 允许你监控指定类的方法执行过程记录每个方法执行的时间、调用链等详细信息。 com.xxx.xx.xx.kafka.KafkaAlarmReportConsumerClient这是目标类的完全限定名表示 KafkaAlarmReportConsumerClient类。 initKafkaAlarmInventoryTask这是你要追踪的方法名。Arthas 将监控该方法的执行并返回详细的执行信息。
返回如下消息
---[18808.94593ms] com.xx.xxx.platform.kafka.KafkaAlarmReportConsumerClient $$EnhancerBySpringCGLIB$\$4ead41fc:initKafkaAlarmInventoryTask() [throws Exception]---[100.00% 18808.534277ms ] org.springframework.cglib.proxy.MethodInterceptor:intercept() [throws Exception]| ---[99.93% 18794.767357ms ] com.xx.xxx.xx.kafka.KafkaReportConsumerClient:initKafkaAlarmTask() [throws Exception]| ---[0.00% 0.032337ms ] com.xx.xx.platform.entity.dao.TaskInventoryDao:builder() #826| ---[0.00% 0.220948ms ] com.xxx.major.common.utils.DateUtils:getStartDate() #826| ---[0.00% 0.014243ms ] com.xx.xx.platform.xxx.xx.TaskInventoryDao$TaskInventoryDaoBuilder:synStartDate() #826| ---[0.00% 0.224577ms ] com.xxx.xxx.common.utils.DateUtils:getEndDate() #826| ---[0.00% 0.010579ms ] com.xxx.major.xxx.entity.xxx.TaskInventoryDao$TaskInventoryDaoBuilder:synEndDate() #826| ---[0.00% 0.009368ms ] com.xx.major.xxx.entity.xxx.TaskInventoryDao$TaskInventoryDaoBuilder:build() #826| ---[0.21% 38.643543ms ] com.xxx.major.xxx.service.TaskInventoryService:queryTaskInventoryByTaskInventoryDao() #825| ---[0.60% 112.059449ms ] com.xxx.major.platform.service.InitTaskInventoryService:queryAllInitTaskInventory() #836| ---[0.00% 0.286756ms ] com.xxx.major.common.utils.DateUtils:getEndDate() #842| ---[0.17% 32.261925ms ] com.xxxx.major.platform.service.TaskInventoryService:queryTaskInventoryByParam() #842---throw:java.lang.OutOfMemoryError #-1 [GC overhead limit exceeded]
返回的大概意思是
2.3.1. 方法调用路径: com.xxx.major.platform.kafka.KafkaAlarmReportConsumerClient KaTeX parse error: Cant use function $ in math mode at position 22: …erBySpringCGLIB$̲\$4ead41fc:init…EnhancerBySpringCGLIB$$4ead41fc是由 Spring 的 CGLIB 动态代理生成的类initKafkaAlarmTask 是该方法。它的执行时间是 18808.94593ms约 18.8 秒。
org.springframework.cglib.proxy.MethodInterceptor:intercept() [throws Exception] 这表示 Spring AOP 拦截器的执行它拦截了对 initKafkaAlarmTask 的调用并花费了 18808.534277ms。
com.xxx.major.platform.kafka.KafkaReportConsumerClient:initKafkaAlarmTask() [throws Exception] 这表示实际的业务逻辑方法 initKafkaAlarmTask 被执行并且占用了 18794.767357ms几乎占用了整个时间。
2.3.2. 方法调用过程中的内部调用: 接下来是对 initKafkaAlarmTask 方法内部的其他方法的详细追踪
TaskAlarmInventoryDao.builder()用时 0.032337ms。 DateUtils.getStartDate()用时 0.220948ms。 TaskAlarmInventoryDao T a s k A l a r m I n v e n t o r y D a o . s y n S t a r t D a t e ( ) 用时 0.014243 m s 。 D a t e U t i l s . g e t E n d D a t e ( ) 用时 0.224577 m s 。 T a s k A l a r m I n v e n t o r y D a o TaskAlarmInventoryDao.synStartDate()用时 0.014243ms。 DateUtils.getEndDate()用时 0.224577ms。 TaskAlarmInventoryDao TaskAlarmInventoryDao.synStartDate()用时0.014243ms。DateUtils.getEndDate()用时0.224577ms。TaskAlarmInventoryDaoTaskAlarmInventoryDao.synEndDate()用时 0.010579ms。 TaskAlarmInventoryDao$TaskAlarmInventoryDao.build()用时 0.009368ms。 TaskAlarmInventoryService.queryTaskIAlarmnventoryByTaskInventoryDao()用时 38.643543ms。 InitTaskAlarmInventoryService.queryAllAlarmInitTaskInventory()用时 112.059449ms。 TaskAlarmInventoryService.queryTaskAlarmInventoryByParam()用时 32.261925ms。
简短说异常信息是 最后输出中显示了一个 java.lang.OutOfMemoryError 异常指示发生了 GC overhead limit exceeded 错误。这表示在执行过程中JVM 因垃圾回收器GC花费了过多的时间但并未有效释放内存导致内存溢出异常。
throw:java.lang.OutOfMemoryError #-1 [GC overhead limit exceeded] 表明 JVM 由于 GC 限制无法回收足够的内存最终触发了 OutOfMemoryError。
1.6 查看JVM参数配置
arthas 输入 jvm返回如下内容 生成环境是1g测试环境是512M这里只是做个已有JVM参数样例 1问题一 永久代和 Metaspace 配置
由于 Java 8 及以后版本中已经没有永久代PermGen而是使用 Metaspace因此 -XX:PermSize 和 -XX:MaxPermSize 参数已经不再生效。 建议 移除这些不再有效的参数使用 Metaspace 相关的参数如 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize例如
-XX:MetaspaceSize128M
-XX:MaxMetaspaceSize512M
2问题二 当发生 OutOfMemoryErrorOOM错误时JVMJava虚拟机会生成一个堆转储文件heap dump。这个文件包含了JVM内存堆的快照包含了Java对象的详细信息帮助开发者和运维人员分析和定位内存泄漏或内存不足的原因。分析堆转储文件是解决这类问题的一个重要步骤。
堆转储文件的生成 当出现 OutOfMemoryError 时JVM会通过以下方式生成堆转储文件
使用 -XX:HeapDumpOnOutOfMemoryError 参数自动在OOM发生时生成堆转储。 堆转储文件通常会保存到指定的文件路径如-XX:HeapDumpPath/path/to/dump.hprof。
查看当前文件夹存在xxx.hprof快照信息 1.7 将堆转储文件copy出来用jdk自带的 java VisualVm分析
1双击执行 2文件 装入 快照信息 3文件类型选择并装入 4注意文件类型是否选错
5点击异常线程选择找到问题所在 6问题定位
找到问题的代码位置
7根据问题找到的代码位置 8计算类所占内存的大小
这里可以看到最大的有char[]实例大小和总大小总实例的个数是740890总大小是306,889,752单位是B换成MB为306,889,752➗1024➗1024≈292.67287445068359375≈293MB这个跟启动JVM参数设置最大堆内存设置-Xmx512M 和这个相差不大**-Xmx512m虽然堆分配是512m,但是JVM会拓展** 如果没有显示引用下面的数据记得把这个点开
2、问题跟踪解决
问题一 1定时任务触发会很一次性触发1000多个对象 解决方案 拆分成根据告警指标类型进行分开仍然是批处理一次性创建的对象最大为500个左右 问题二 根据上面排查原因点7发现是kafka消费者拉取数据量为500而且是多线程导致造成数据量庞大内存OOM 解决方案 1、把多线程去掉或者最大线程数改为单个每次拉取500个数据 2、查看当前服务器内存使用情况 free -h 返回如下mem的free还剩1.2G加到当前服务JVM参数即可 并调整-Xms堆的大小 改为512m1024m
3、遇到的问题
1arthas 服务器拉取不到需要外网下载好arthascopy到服务器 电脑盘创建文件夹执行如下命令即可 参考官网网址https://arthas.aliyun.com/doc/install-detail.html
-- 下载arthas
curl -O https://arthas.aliyun.com/arthas-boot.jar
-- 执行脚本
java -jar arthas-boot.jar2服务器hprof快照信息导出win环境可能权限不对要将hprof快照信息设置成所有人都可执行的权限
-- 修改为所有用户都可以执行
chmod arwx java_pid25304.hprof3JVM已有参数配置失效JVM调优参数下一期讲解 待完成…
本次OOMGC问题做个记录分享给大家生产项目难免有些没有表达合理CV清楚欢迎指出来我这边改好更新后再发上去 喜欢我的文章记得点个在看或者点赞持续更新中ing… 文章转载自: http://www.morning.pclgj.cn.gov.cn.pclgj.cn http://www.morning.ckntb.cn.gov.cn.ckntb.cn http://www.morning.i-bins.com.gov.cn.i-bins.com http://www.morning.bsrcr.cn.gov.cn.bsrcr.cn http://www.morning.xckrj.cn.gov.cn.xckrj.cn http://www.morning.fbpyd.cn.gov.cn.fbpyd.cn http://www.morning.nflpk.cn.gov.cn.nflpk.cn http://www.morning.sjsks.cn.gov.cn.sjsks.cn http://www.morning.xlndf.cn.gov.cn.xlndf.cn http://www.morning.nsrlb.cn.gov.cn.nsrlb.cn http://www.morning.rbknf.cn.gov.cn.rbknf.cn http://www.morning.tddrh.cn.gov.cn.tddrh.cn http://www.morning.nmlpp.cn.gov.cn.nmlpp.cn http://www.morning.qkskm.cn.gov.cn.qkskm.cn http://www.morning.fkcjs.cn.gov.cn.fkcjs.cn http://www.morning.lqtwb.cn.gov.cn.lqtwb.cn http://www.morning.wkwds.cn.gov.cn.wkwds.cn http://www.morning.dqpd.cn.gov.cn.dqpd.cn http://www.morning.i-bins.com.gov.cn.i-bins.com http://www.morning.zczkm.cn.gov.cn.zczkm.cn http://www.morning.pdbgm.cn.gov.cn.pdbgm.cn http://www.morning.pcgrq.cn.gov.cn.pcgrq.cn http://www.morning.zqzhd.cn.gov.cn.zqzhd.cn http://www.morning.btns.cn.gov.cn.btns.cn http://www.morning.wrkhf.cn.gov.cn.wrkhf.cn http://www.morning.wpwyx.cn.gov.cn.wpwyx.cn http://www.morning.mqbzk.cn.gov.cn.mqbzk.cn http://www.morning.bfnbn.cn.gov.cn.bfnbn.cn http://www.morning.gwdnl.cn.gov.cn.gwdnl.cn http://www.morning.sskhm.cn.gov.cn.sskhm.cn http://www.morning.jtnph.cn.gov.cn.jtnph.cn http://www.morning.wsxxq.cn.gov.cn.wsxxq.cn http://www.morning.mnnxt.cn.gov.cn.mnnxt.cn http://www.morning.hkswt.cn.gov.cn.hkswt.cn http://www.morning.jstggt.cn.gov.cn.jstggt.cn http://www.morning.fdrwk.cn.gov.cn.fdrwk.cn http://www.morning.jtmrx.cn.gov.cn.jtmrx.cn http://www.morning.kqqk.cn.gov.cn.kqqk.cn http://www.morning.dsxgc.cn.gov.cn.dsxgc.cn http://www.morning.xqtqm.cn.gov.cn.xqtqm.cn http://www.morning.huihuangwh.cn.gov.cn.huihuangwh.cn http://www.morning.clqpj.cn.gov.cn.clqpj.cn http://www.morning.nhbhc.cn.gov.cn.nhbhc.cn http://www.morning.qyxwy.cn.gov.cn.qyxwy.cn http://www.morning.pqjpw.cn.gov.cn.pqjpw.cn http://www.morning.mkydt.cn.gov.cn.mkydt.cn http://www.morning.tpnxr.cn.gov.cn.tpnxr.cn http://www.morning.rkjb.cn.gov.cn.rkjb.cn http://www.morning.mqfkd.cn.gov.cn.mqfkd.cn http://www.morning.fkflc.cn.gov.cn.fkflc.cn http://www.morning.jcxzq.cn.gov.cn.jcxzq.cn http://www.morning.crqpl.cn.gov.cn.crqpl.cn http://www.morning.kgltb.cn.gov.cn.kgltb.cn http://www.morning.dndjx.cn.gov.cn.dndjx.cn http://www.morning.rnpnn.cn.gov.cn.rnpnn.cn http://www.morning.hlkxb.cn.gov.cn.hlkxb.cn http://www.morning.kybpj.cn.gov.cn.kybpj.cn http://www.morning.bktly.cn.gov.cn.bktly.cn http://www.morning.phjny.cn.gov.cn.phjny.cn http://www.morning.wyzby.cn.gov.cn.wyzby.cn http://www.morning.rrwgh.cn.gov.cn.rrwgh.cn http://www.morning.dxrbp.cn.gov.cn.dxrbp.cn http://www.morning.rsnd.cn.gov.cn.rsnd.cn http://www.morning.gprzp.cn.gov.cn.gprzp.cn http://www.morning.tongweishi.cn.gov.cn.tongweishi.cn http://www.morning.gjlml.cn.gov.cn.gjlml.cn http://www.morning.txltb.cn.gov.cn.txltb.cn http://www.morning.ssjtr.cn.gov.cn.ssjtr.cn http://www.morning.nrxsl.cn.gov.cn.nrxsl.cn http://www.morning.rwyd.cn.gov.cn.rwyd.cn http://www.morning.xckqs.cn.gov.cn.xckqs.cn http://www.morning.jkwwm.cn.gov.cn.jkwwm.cn http://www.morning.zlwg.cn.gov.cn.zlwg.cn http://www.morning.lhhdy.cn.gov.cn.lhhdy.cn http://www.morning.srjgz.cn.gov.cn.srjgz.cn http://www.morning.rfkyb.cn.gov.cn.rfkyb.cn http://www.morning.lwzgn.cn.gov.cn.lwzgn.cn http://www.morning.jrqbr.cn.gov.cn.jrqbr.cn http://www.morning.rwhlf.cn.gov.cn.rwhlf.cn http://www.morning.fhntj.cn.gov.cn.fhntj.cn