Java之JVM调优案例分析与实战(2) - 集群间同步导致的内存溢出
2014-01-16 09:29
633 查看
环境:一个基于B/S的MIS系统,硬件为两台2个CPU、8GB内存的HP小型机,服务器是WebLogic 9.2,每台机器启动了3个WebLogic实例,构成一个6个节点的亲合式集群。
说明:由于是亲合式集群,节点间没有进行Session同步,但是有一些需求要实现部分数据在各个节点间共享。开始这些数据存放在数据库中,但是由于读写频繁竞争很激烈,对性能影响较大,后面使用JBossCache构建了一个全局缓存。
全局缓存启用后,服务正常使用了较长一段时间。
问题:最近不定期地多次出现内存溢出问题。
分析:在不出现内存溢出异常的时候,服务内存回收状况一直正常,每次内存回收后都能恢复到一个稳定的可用空间,开始怀疑是程序的某些不常用的代码路径中存在内存泄漏,但是管理员反映最近程序并未更新或升级过,也没有进行什么
特别操作。只好让服务带着-XX:+HeapDumpOnOutOfMemoryError参数运行了一段时间。在最近一次溢出之后,管理员发回了heapdump文件,发现里面存在着大量的org.jgroups.protocols.pbcast.NAKACK对象。
JBossCache是基于自己的JGroups进行集群间的数据通信,JGroups使用协议栈的方式来实现收发数据包的各种所需特性的自由组合,数据包接收和发送时要经过每层协议栈的up()和down()方法,其中的NAKACK栈用于保障各个包
的有效顺序及重发。
由于信息有传输失败需要重发的可能性,在确认所有注册的GMS(GroupMembership Service)的节点都收到正确的信息前,发送的信息必须在内存中保留。此MIS的服务端中有一个负责安全校验的全局Filter,每当接收请求时,均会更新
一次最后的操作时间,并且将这个时间同步到所有节点中,使得一个用户在一段时间内不能在多台机器上登录。在服务器使用过程中,往往一个页面会产生数次乃至数十次的请求,因此这个过滤器导致集群各个节点之间的网络交互非常频繁。
当网络情况不能满足传输要求时,重发数据在内存中不断地积累,很快就产生了内存溢出。
这个案例中的问题,既有JBossCache的缺陷,也有MIS系统实现方式上的缺陷。JBossCache官方的mailist中讨论过很多次类似的内存溢出异常问题,据说后续版本有了改进。而更重要的缺陷是这一类被集群共享的数据如果要使用类似JBossCache
这种集群缓存来同步的话,可以允许读操作频繁,因为数据在本地内存有一份副本,读取的动作不会耗费多少资源,但不应当有过于频繁的写操作,这会带来很大的网络同步的开销。
说明:由于是亲合式集群,节点间没有进行Session同步,但是有一些需求要实现部分数据在各个节点间共享。开始这些数据存放在数据库中,但是由于读写频繁竞争很激烈,对性能影响较大,后面使用JBossCache构建了一个全局缓存。
全局缓存启用后,服务正常使用了较长一段时间。
问题:最近不定期地多次出现内存溢出问题。
分析:在不出现内存溢出异常的时候,服务内存回收状况一直正常,每次内存回收后都能恢复到一个稳定的可用空间,开始怀疑是程序的某些不常用的代码路径中存在内存泄漏,但是管理员反映最近程序并未更新或升级过,也没有进行什么
特别操作。只好让服务带着-XX:+HeapDumpOnOutOfMemoryError参数运行了一段时间。在最近一次溢出之后,管理员发回了heapdump文件,发现里面存在着大量的org.jgroups.protocols.pbcast.NAKACK对象。
JBossCache是基于自己的JGroups进行集群间的数据通信,JGroups使用协议栈的方式来实现收发数据包的各种所需特性的自由组合,数据包接收和发送时要经过每层协议栈的up()和down()方法,其中的NAKACK栈用于保障各个包
的有效顺序及重发。
由于信息有传输失败需要重发的可能性,在确认所有注册的GMS(GroupMembership Service)的节点都收到正确的信息前,发送的信息必须在内存中保留。此MIS的服务端中有一个负责安全校验的全局Filter,每当接收请求时,均会更新
一次最后的操作时间,并且将这个时间同步到所有节点中,使得一个用户在一段时间内不能在多台机器上登录。在服务器使用过程中,往往一个页面会产生数次乃至数十次的请求,因此这个过滤器导致集群各个节点之间的网络交互非常频繁。
当网络情况不能满足传输要求时,重发数据在内存中不断地积累,很快就产生了内存溢出。
这个案例中的问题,既有JBossCache的缺陷,也有MIS系统实现方式上的缺陷。JBossCache官方的mailist中讨论过很多次类似的内存溢出异常问题,据说后续版本有了改进。而更重要的缺陷是这一类被集群共享的数据如果要使用类似JBossCache
这种集群缓存来同步的话,可以允许读操作频繁,因为数据在本地内存有一份副本,读取的动作不会耗费多少资源,但不应当有过于频繁的写操作,这会带来很大的网络同步的开销。
相关文章推荐
- Java之JVM调优案例分析与实战(3) - 堆外内存导致的溢出错误
- Java之JVM调优案例分析与实战(4) - 外部命令导致系统缓慢
- Java之JVM调优案例分析与实战(1) - 高性能硬件上的程序部署策略
- 深入学习Java JVM - 调优案例分析与实战
- Java之JVM调优案例分析与实战(5) - 服务器JVM进程奔溃
- Java VisualVM分析JVM内存溢出
- 《Spark商业案例与性能调优实战100课》第29课:彻底解密Spark 1.6.X以前Shuffle中JVM内存使用内幕及配置最佳实践
- java内存溢出分析工具:jmap使用实战
- JVM笔记——调优案例分析与实战
- JVM——java 内存区域与内存溢出分析
- Java 内存区域和GC机制以及JVM(Java虚拟机)优化大全和案例实战
- java内存溢出分析工具:jmap使用实战
- 笔记:深入理解JVM 第5章 调优案例分析与实战
- JVM调优案例分析与实战:高性能硬件上的程序部署策略
- Java调优之jvm和线程的内存分析
- JVM调优案例分析与实战
- java学习——java基础(十二)之内存泄漏、内存溢出及JVM内存调优
- Java多线程编程-(9)-ThreadLocal造成OOM内存溢出案例演示与原理分析
- 《JVM 系列》- 内存溢出实战分析
- JVM之调优案例分析与实战