如何快速定位OOM问题
OOM的原因
一次性申请过多的对象
更改申请对象的数量。(分页)
内存资源耗尽 未释放
找到未释放的对象进行释放。
本身资源不够
查看堆信息:
JDK 8: jmap -heap [pid]
JDK 11往后:jhsdb jmap --heap --pid [pid]
通过dump定位
系统已经OOM挂掉了
- 提前设置
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=[指定的存放路径]
需要保证服务器的硬盘空间够大,因为该设置会记录系统在整个运行过程中所有的对象信息,占用空间。
发生OOM后,会生成java_pidxxxxx.hprof
的heap dump文件。
- 使用JProfiler进行查看
JVM性能分析工具 Jprofiler - 残城碎梦 - 博客园 (cnblogs.com)
- 找到与业务相关的类 - 右键,使用选定对象
- 选择 传入引用,确定。
- 显示到GC根(GC Root)的路径,确定
- 根据显示的线程堆栈,查看代码进行分析。
系统运行中,还未OOM
方式一 导出dump文件
jmap -dump:format=b,file=[outputFileName.hprof] [pid]
在系统运行阶段导出dump文件,会造成一次FullGC、STW(Stop The World,所有线程中断)。但不导出dump文件的话,时间成本要增高很多