0
点赞
收藏
分享

微信扫一扫

线上OOM:GC Overhead Limit Exceeded异常排查(一)

一、背景

上周五,其他项目组违背了周五不能发版的规定,​​18:30​​下班前两个系统发了新版

​19:30​​​运营反馈系统很卡,华为云​​CPU​​100%报警

二、解决思路

因为应用服务器不同项目组是共用的,影响到我负责的系统,所以我也帮忙排查

第一直觉判断应该是内存泄露或大对象

因为数组内存分配在​​Oracle​​​ ​​JDK8​​​空间必须是连续的(​​IBM​​​ ​​J9​​​不是),如果大对象无法申请到足够的内存,那么就会​​OOM​

检查周五提交的代码记录,发现​​select *​​​和​​where​​​条件名字数据在​​20W​​​,并且使用​​Stream.collect​​​产生新集合,局部变量一直持有原集合,预估数据量在​​40W​​​左右,并且接口属于数据同步类型的,基本上每2分钟一次拉取,因为大数据查询耗时,算上并发时客户端数量在20个左右,峰值数量在​​800W​​​,这仅仅是其中一个数据同步接口,如果应用服务器其他接口内存申请触发​​GC​​​,处理延迟,峰值更高,由于都存在引用,​​full gc​​​也无法回收内存,故​​JVM​​​抛出​​OOM​

先回滚了代码,定位问题大概用了20-30分钟

三、思考

抛开代码​​code review​​和开发的问题,谈谈大对象的优化

通常大对象发生的场景

  1. 数据导入导出
  2. 文件服务器
  3. 批处理任务 ......

优化的方法

  1. 可以每次取小量,使用offset记录偏移量,在循环中处理
  2. 在使用完后的数据,后续不用时,对局部变量赋值为null,这种在处理耗时较长场景提升较大
  3. 尽量不要查出数据在应用中聚合统计
  4. 流处理(​​mybatis支持流和游标返回数据​​)

原理就是寻找大数据小内存的通用解

举报

相关推荐

0 条评论