JVM内存溢出问题分析(11.05)

对于JVM内存溢出,实际上和堆内存相关的主要有两点,即:

一个就是本地的堆内存出现溢出,即内存不断的增长但是又不能离开被GC回收,导致了最终的内存溢出。而实际的原因一方面是我们初始化的堆内存分配过小,一种就是在应用程序中本身有资源和内存没有及时释放情况。

另外一个就是GC 开销超过限制,造成原因Java 进程98%的时间在进行垃圾回收,恢复了不到2%的堆空间,最后连续5个(编译时常量)垃圾回收一直如此。所以你可以看到一直频繁的在进行full gc操作,但是内存使用一直无法降低下来,最终还是导致堆内存溢出。

对于osb的服务运行,我们在前面已经分析过最常见的内存溢出情况就是在短时间内出现了大数据量的服务报文调用,如果这个服务运行时长本身又很长,那么就代表连接一直在保持,而报文持续在内存中进行序列化和反序列化处理,而且无法及时释放,将快速的导致最终的内存溢出。一个50M左右的报文调用,如果同时2到3个并发调用那么很容易马上就最终导致内存溢出的情况。这也是我们在SOA管控上面对服务报文量进行及时控制的原因,即一发现了有大报文数据量调用,那么就快速的释放内存。

上面这个是在日志里面发现的一个提示信息,即最大现场约束达到了。在堆内存还剩余25%的时候,日志里面马上就出现了上面最大现场约束已经达到的提示信息。

但是最大线程约束限制达到具体和后续的内存溢出什么关系,暂时无法关联上。

从日志可以看到,在不到1分钟的时间里面活动线程从2个迅速的增加到20个活动线程,同时内存剩余从25%快速的降低到只剩余1%。而实际上查看accesslog,实际上在这1到2分钟里面,日志文件记录到的访问请求不到50个访问,而且根本没有大报文的数据访问请求。

这也是导致我们很难快速的分析出来究竟是什么原因导致出现了活动线程快速的增加,同时内存被快速耗尽。

accepting connection migration with

正在接受连接迁移,为何会出现大量的连接迁移,具体什么情况下会触发连接迁移?如果本身节点服务调用并发和数据量都没有问题的话,那么很可能是其它节点的请求连接迁移到该节点而导致的线程池被占满,并进一步导致内存耗尽和内存泄露。

对于连接迁移,在oracle support网站给出了一个说明,具体如下:

A customer is on a coherence cluster configured using version 12.2.1.0.6. This cluster is with the JVMs of heap size great than 20 GB and experiences significant GC pauses sometimes at run time. Intermittently such long GC pauses are leading to a tmb:// connection failures and there after migration is triggering. Until it is good and working as expected but the migrated connections are not being succeeded. At later stages in the cluster tmb:// migration calls are growing and the members in the cluster scrawling/freezing to process the requests. The communication delays in the cluster are reported very high as follows.

Initial GC led to communication delay, which led to excessive “connection migration”, which led to more and longer communication delays, which eventually lead to many nodes left cluster and rejoin, but some failed rejoining.

===集群中的两个节点之间经历了一个沟通延迟,很可能是远程gc操作引起的

Experienced a 1172 ms communication delay (probable remote GC) with Member

对于该延迟,在support网站一篇文章仍然提到不排除是由于节点间的网络通信延迟导致,如果出现该情况可以进一步诊断的方法如下:

1. Collect more data, Logs of all nodes including diagnostic logs from OSB/SOA domain.

-Dtangosol.coherence.log.level=9

-Dtangosol.coherence.log=

2. GC logs of all servers in the domain.

-XX:-PrintGC, -XX:-PrintGCDetails, and -XX:-PrintGCTimeStamps -verbose:gc or -Xloggc:file

3. Network command data

netstat -s

ethtool -S

对于OSB集群中的某一到两个节点出现内存溢出的情况,其诊断的难点是在单节点分析基础上增加了cluster集群和节点间通信,连接迁移等其他外在影响。因此要最终定位导致的原因往往并不太容易。