今天测试同学反馈API耗时很长,超过3秒的比例很高。 查看日志发现,小部分请求耗时比较大,约2秒左右,但是比例不高,与反馈比例有点不一致。后来发现是有一台服务器停止工作了(进程假死),对请求没有响应,也没有拒绝,重启后问题缓解。 因为第一次出现,没有引起重视。但是过了几个小时候,相同的问题又出现在另外一台服务器上,狗日的墨菲定律。
本来应该早就该发现的
Full GC
,频率很快,差不多2秒一次(一次时间约1.5秒)。仔细分析日志可以看出,Full GC后回收的内存特别少jstat -gcutil PID
: 发现Full GC高达三十多万次接下来就要定位占用内存的元凶了
jvmvisual
分析,通过类的排序看到一些类的实例数特别多。但是跟算法同学计算了一下,基本还算正常。然后通过占用内存数排序,发现double[]
占用了63%的内存,我们怀疑可能是算法用到了double[],但是没有及时释放,存在内存泄漏(感觉很明显了)。jvmvisual
看不出来对象之间的引用关系,我们也很难判断是哪些对象引用了double[]
。我们就在代码中搜索double[]
,但是分析了好久,也没有看出内存泄漏的影子。mat(Eclipse Memory Analyzer )
,最后使用mat来执行内存分析(因为直到mat分析完毕,jhat都还没打开内存文件)jstat -gcutil PID
查看的话,就可以很快的地发现Full GC的问题