一招定位JAVA_OOM中的大对象
java开发中,最令人憎恨的便是跑着跑着出现OOM
内存溢出对于新手来说最为头痛,隐蔽且难以排查。
对于正常应用来说500MB内存足够了,出现OOM一般是内存中持有太多不可释放对象,主要排查以下几点:
- list 或者 MAP 装太多,而且不释放,较多存在于静态引用中
- 数据库或者读文件一次读取太多了,比如20W行数据库记录一下加载到内存中, 较多存在于没有limit参数,或者统计sql
- threadlocal,StringBuffer, ByteBuffer等
内存泄漏的一般伴随着如下现象:
- OOM伴随着疯狂的fullgc. 一般1-3S一次
- cpu的异常增高,100%, 200%, 此时主要是JVM疯狂做无效full gc 导致
- 服务假死,不可访问,重启服务后恢复正常。由于GC造成的
Stopwrold
导致
那么这种问题如何排查呢,这里介绍一个通用的流程:
- oom后导出内存镜像,使用命令为
jmap -dump:format=b,file=文件名.hprof <进程ID>
- 使用
JAVA_Memory_Analyzer_Tool
进行分析。
工具分析操作步骤如下:
图片中,Objects
代表对象在内存中的数量。
上面的操作将会将内存的所有对象按照包名分组并排好序, 接着只需去查看自己业务包下面哪个对象最多,再分析其存在是否合理,基本就能排查出问题所在了。
附: oom一般是出现问题后手动导出,但是更为推荐的是在java启动中增加参数,出现oom时JVM将会自动到处镜像。方便排查。
This post is licensed under CC BY 4.0 by the author.