java 一次OOM故障 分析
先看了下监控 发现内存在逐渐增加 ,然后cpu 有一个飙升的情况, 后 java 进程被杀,
OOM确实会造成CPU飙升,系统卡顿,然后系统会选择杀死某些进程以释放空间就把java杀了
第一步 补救措施
恢复java , 重新设置合适的JVM 初始堆与最大堆内存 ,重新设置 swap交换空间大小
-Xmx****m:
-Xms****m;
cat /proc/sys/vm/swappiness
二 ,查找具体内存溢出地方查漏补缺
看一下服务器内存分配
查看linux内存使用情况
$ free -m
查看java 进程/线程对系统的占用情况
$ top -c
$ top -Hp 22251
jmap -heap 22251
下载当前的java线程栈
jstack -l 22251 > /stackLog.txt
jvisualvm 打开查看
查询 对应的线程情况,发现都是gc线程导致的
dump java堆数据
jmap -dump:live,format=b,file=/dump_.dat 22251
加载对比 堆文件,发现 对象增多,初步定位到问题。发现是定时器循环, 内ArrayList 存储了每次探测接口响应的结果,每次探测完都塞到 ArrayList 里去分析,由于 Bean 对象不会被回收,这个属性又没有清除逻辑,所以在服务十来天没有上线重启的情况下,这个 Map 越来越大,直至将内存占满。
三、本文总结
遇到线上问题不要慌,首先恢复环境 ,再确认排查问题的思路:
- 查看日志
- 查看CPU情况
- 查看TCP情况
- 查看java线程,jstack
- 查看java堆,jmap
- 通过分析堆文件,寻找无法被回收的对象