①VM参数准备:
设置启动参数(设置堆大小、内存溢出时往指定目录生成dump文件)
dump文件:文件是内存转储文件,也称为内存快照文件(内存镜像)
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=E:\OnePlus\dump
-Xmx1024m -Xms1024m
②编写代码并启动服务
③开启监控
a.打开jdk自带工具,JVisualVM
b.使用jdk自带jstat命令
在jdk\bin目录下输入如下命令
jstat -gc -t -h8 6084 1000
//-gc表示打印gc信息
//-t表示打印程序总运行时间
//-h8表示每输出八行打印一次表头
//6084为pid
//1000 为一秒打印一行信息
③Postman调用接口
③运行并观测现象
使用JVisualVM观测Cup和堆内存
观测到内存和cpu猛增
观测到伊甸园区和老年代已经被塞满
①观测到fullGC从一开始的2次已经猛增到43次,并且还在持续增长
②算一下FullGC总用时和程序总用时的比值,(83.933-58.685)/(652.1-626.2)=0.974 =97%,FullGC会造成STW导致应用挂起不可用
在指定目录生成了dump文件
④结论
1.控制台打印OOM;
2.在指定文件夹生成dump文件;
3.超过98%的时间用来做GC并且回收了不到2%的堆内存时会抛出此异常 java.lang.OutOfMemoryError: GC overhead limit exceeded
⑤分析Dump文件
使用工具MAT
1.加载生成的dump文件
2.选择生成泄漏报告
查看mat泄漏报告
可从mat工具的提示中看到List里包裹的User占比百分之九十三
3.分析问题
字段说明:
浅堆(Shallow Heap) 表示对象结构本身所占内存的大小,不包含引用的对象,单位 bytes。 深堆(Retained Heap) 表示这个对象以及 仅被 它所直接或间接引用的对象所占的内存之和,单位 bytes,表示一个对象被GC回收后可以真实释放的内存大小。
outgoing references :表示该对象的出节点(被该对象引用的对象)。
incoming references :表示该对象的入节点(引用到该对象的对象)。
4.定位出错位置
通过使用mat工具的线程信息(下图中的黄色小齿轮)
即可看到UserController类oom方法中List里包裹了太多的User
实际的线上环境可以通过对比不同时期的dump文件从而分析内存泄漏等问题
同时搭配多种监控工具观测如arthas