一、问题
之前做了一个定时报告功能,主要是去获取一定周期的数据,统计分析后通过邮件形式发送报告。
程序部署好了,运行起来了,每天都收到邮件了,然后后面就没管了,突然一天登上服务器发现cpu和内存占用很高,然后再一看是的那个程序,然后再去看我的邮箱,已经有一周没有收到邮件了。
二、排查
首先通过top命令去查看进行情况
发现有几个线程一直都是cpu占用40多,内存21%左右
然后通过jstack 16735,查看线程占用情况取其中一个进行分析
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007f468802b000 nid=0x4168 runnable
说明在gc上有问题
然后接下来查看内存,jmap -heap 16735
此时看的Eden和年老代使用率达到100%,发生了full GC
再通过jstat命令看看gc回收情况
天啦,发生了157W次fullGC!!!
基本可以确定是发生了大量FullGC导致的问题
那么为什么会发生FullGC呢??
开始排查代码,发现我在获取数据时,是从ES中获取的,并且使用了Scroll做分页获取,当时我复现之后,发现查询的数据量很大,有很多大对象产生。
三、解决方案
找到问题,首先去优化代码,将ES的查询做优化,在循环体内不再去创建新的对象,每次做完查询将对象置为null等操作
同时我发现部署项目的时候,设置了堆的大小为128M,太小了,我改为了512M
打包部署,目前运行两周,没有出现上述问题,还待观察中。。
PS:自己理解不是很深入,如有不对,请大家指正。