我有一个已经运行了一段时间的zookeeper实例......(Java 1.7.0_131
,ZK 3.5.1-1
),-Xmx10G -XX:+UseParallelGC
。
最近发生了领导层变更,法定人数中大多数情况下的内存使用量从大约200MB增加到2GB +。我进行了jmap
转储,我发现有趣的是,有很多byte[]
序列化数据(> 1GB)没有GC Root,但尚未收集。< / p>
(这是ByteArrayOutputStream
,DataOutputStream
,org.apache.jute.BinaryOutputArchive
或HeapByteBuffer
,BinaryOutputArchive
)。
在选举更改前不久,查看gc日志,完整的GC每4-5分钟运行一次。选举结束后,任期阈值从1增加到15(最大值),并且完整的GC运行的次数越来越少,最终甚至连几天都没有运行。
几天之后,突然,神秘地对我来说,一些事情发生了变化,每隔4-5分钟就会有Full GC运行,内存会回落到200MB左右。
我在这里感到困惑的是,如此多的内存可以没有GC Root,而不是由完整的GC收集。我甚至试过几次从GC.run
触发jcmd
。
我想知道ZK原生土地上的东西是否存在于这个记忆中,或者泄漏了这个记忆......这可以解释它。
我正在寻找任何调试建议;我正计划升级Java 1.8
,也许是ZK 3.5.4
,但是在继续升级之前,我真的想要根源。
到目前为止,我已经使用了visualvm,GCviewer和Eclipse MAT。
答案 0 :(得分:1)
我不是ZK的专家。但是,我已经在Weblogic上调整JVM了一段时间,基于这些信息,我觉得你的配置正在产生堆的扩展和缩小(-Xmx10G -XX:+ UseParallelGC)。因此,也许您应该尝试使用-Xms10G和-Xmx10G来避免此大小调整。重要的是,每次调整JVM大小时都会执行完整的GC,因此避免此过程是最大限度地减少完整垃圾收集次数的好方法。
请阅读本文
“当Hotspot JVM启动时,堆,年轻代和perm生成空间都是 分配到由-Xms,-XX:NewSize和-XX:PermSize参数确定的初始大小 分别根据需要增加最大保留大小,即-Xmx, - XX:MaxNewSize和-XX:MaxPermSize。如果是,JVM也可能在运行时缩小实际大小 内存不需要与最初指定的一样多。 但是,每个调整大小活动都会触发一个 完整垃圾收集(GC),因此影响性能。作为最佳实践,我们 建议您使初始和最大尺寸相同“
来源:http://www.oracle.com/us/products/applications/aia-11g-performance-tuning-1915233.pdf
如果你能提供你的gc.log,那么彻底分析这个案例会很有用。
祝你好运, RCC