曾经在生产环境中遇到过OOM异常,现在通过实践回顾一下当时的排查和处理思路。
1. 我有一张企业表有1200多万条数据。
2. 我在java程序中写一个接口查询全表数据
controller层
service层
dao层
mapper.xml
3. 将java程序打包上传至centos7.x服务器
通过mobaxterm打包上传即可。
4. 通过nohup java -jar命令运行jar包
为防止影响服务器上的其他应用,我指定JVM堆的大小为128MB,可以看到父进程号是:206168
5. postman调用接口
6. 查看centos服务器的变化,注意观察CPU变化
可以看到,调接口的一瞬间,服务器的206168进程的cpu已经飙升到了436.9%
7. 使用top -Hp pid 来查看2006168进程中具体的线程cpu占用情况
-H 线程模式
-p 指定进程ID
可以看到CPU占用率较高的都是GC线程
8. 找到进程中的具体占用CPU高的其中一个子进程
我们这里取206170线程id
9. 将线程id转为16进制
使用命令:printf "%x\n" 206170
- jstack -l 父进程的pid | grep 线程的pid(16进制),查看JVM日志在做什么?
发现这里是GC线程占用的CPU较高。
然后再看项目日志输出,发现也报了OOM异常
- jMap -histo 父进程pid | head -n 10 ,查看占用内存最多的十个对象
发现了一个业务实体类对象,创建的实例有一万八千多个,占用了3444112byte的空间。
- 找到了具体的业务对象,去业务当中具体排查。
根据CompanyAll16对象,去找引用到他,而且近期改动过的地方,发现是查了全表导致的OOM异常。 至此,OOM问题排查完毕