一次异常OOM问题学习跟踪的过程

发布时间 2023-12-22 06:55:09作者: 济南小老虎

摘要

春节后第一周一个项目出现了OOM的问题.
平台研发和产品研发跟踪了接近一周的时间也没有最终确认问题根因.
这里总结一下整个过程, 希望以后在遇到相同问题时会有进一步的结论.
产品的稳定运行离不开所有人的努力. 不管是框架,产品平台还是其他. 

现象和暂时的结论

产品需要在月初处理一个月度数据. 
但是最近发现处理过程非常缓慢,并且经常无法处理完成. 
并且会导致处理数据的服务器卡顿.CPU暴高.出现响应变慢的问题. 
后台进行了mat的分析工作. 然后发现有一个可以的memory leak
但是比较奇怪的是 他的对象名为 hibernate的queryplancache里面包含了 完全相同的 接近3000个表的信息
每一个里面有 11k 这么大,并且对象有 接近200万个, 直接导致 占用了 20G的对内存.
导致异常. 

根据平台开发的分析. 发现此处可能为hibernate的bug:
理论上默认值 hibernate 的 queryplancache 最多占用2G的内存, 但是实际上占用了20G.
应该是业务的代码触发了hibernate的bug导致缓存信息放到内存中没有释放,出现了OOM.

分析过程

获取返回过来的 dump 文件, 使用 mat 进行简要分析
打开  leak suspect 进行查看

建议可以先查看 系统的概要信息对系统有一个简单的了解:
Leak Suspects
» System Overview
System Overview
 Heap Dump Overview 
 System Properties 
 Thread Overview 
 Top Consumers 
 Class Histogram 


打开 Problem Suspect 1

理论上第一个问题的概率最高
建议选中detail 打开详细进行查看. 

在memory leak的界面可以看到很多内容. 

The thread org.apache.tomcat.util.threads.TaskThread @ 0x5e901df80 http-nio-5200-exec-2 
keeps local variables with total size 6,885,096,656 (66.41%) bytes.
此命令会将 占用最多内存的堆栈信息展示出来. 存在未的风险是最大的. 

Shortest Paths To the Accumulation Point 
累积点的最短路径
Accumulated Objects in Dominator Tree
累积对象所在树
Accumulated Objects by Class in Dominator Tree 
对象树种按照类进行分组的对象信息
All Accumulated Objects by Class 
按照类进行分组的所有的对象信息
Thread Details 
线程信息
    Thread http-nio-5200-exec-2
    Thread Properties
    Thread Stack
    线程堆栈信息

最快分析方法

打开最后面的 Thread Details -> Thread Stack
可以反馈给对应开发. 确认问题场景等. 

打开 All Accumulated Objects by Class 
可以查看哪些对象 占用内存最多
可以通过这个内容 确定上一个场景里面的业务数据, 便于研发人员进一步的定位问题原因. 
发现精确的数据, 比如发现excel的文件信息. 发现异常的用户id等. 

打开 Accumulated Objects by Class in Dominator Tree 
或者是上面一个 可以看到对象的上下级信息, 便于分析是那一块的问题
可以快速发现是否是产品bug或者是比较深层次的问题. 

关于 in going 以及out going 等名词的含义

in going:   查看对象被谁引用,右键->list objects -> with ingoing references
out going:  查看对象为什么耗内存,我们看到一个线程池占用了>25mb的内存,右
             键->list objects -> with outgoing references
Shallow Size: 对象自身占用的内存大小,不包括它引用的对象
Retained Size:被GC后Heap上释放的内存大小,
               即当前对象大小+当前对象可直接或间接引用到的对象的大小总和