上一篇文章修改了JVM配置后,发现随着放量 Concurrent ModeFailure 出现的越来越频繁,说明调优JVM没有根本解决问题;
通过 jstat -gcutil 跟踪进程发现多次CMS GC之后OLD区占比就超过了CMS GC设定的阀值,怀疑有内存泄露;
通过 jmap -heap 发现有某些对象一直在涨,但是由于都是基础对象,很难判断是哪个模块问题,打算用 jhat 来详细的分析一次,因为工程数据太多,所以只加载了一个模块的数据来作为突破口(jhat特别耗内存),8G也分析了好久啊。
通过 jhat 发现:
1、缓存里面的数据较多,处于一直增长;(影响较小,原先也不是很大)
2、有些异步队列由于消息发送阻塞或者处理不及时导致队列越来越长;
针对1,限制缓存大小(进程内部缓存)即可;
针对2,限制异步队列大小,超过设定队列大小(比如10w)就抛除对象,这个方法是暂时的;现在网络消息是通过tcp发送的,可以通过udp发送或者干脆做一个消息队列(总线),减少各系统的耦合性。当然,这些以后慢慢优化。
这两点做完,CMS GC正常,不是内存泄露。以后加缓存和设置队列要悠着点。
Good night.