我们将软件从jboss 4.0.5GA升级到5.0.1GA并注意到一小时左右(或在某些情况下为90分钟)性能急剧下降。
同时,垃圾收集器日志显示较小的垃圾收集时间从0.01秒跳到1.5秒,每次清除堆的数量从之前的~400MB减少到之后的~300MB。 (参见GC查看器图1)
我们认为这些都是同一根本原因的症状。
jvm设置是:
-server -Xms2048m -Xmx2048m -XX:NewSize=384m -XX:MaxNewSize=384m
-XX:SurvivorRatio=4 -XX:MinHeapFreeRatio=11 -XX:PermSize=80m -verbose:gc
-XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+DisableExplicitGC
-Djava.awt.headless=TRUE -DUseSunHttpHandler=TRUE
-Dsun.net.client.defaultConnectTimeout=25000
-Dsun.net.client.defaultReadTimeout=50000 -Dfile.encoding=UTF-8
-Dvzzv.log.dir=${ercorebatch.log.dir} -Xloggc:${ercorebatch.log.dir}/gc.log
-Duser.language=it -Duser.region=IT -Duser.country=IT -DVFjavaWL=er.core.it
生产环境是T5220或T2000硬件,带有32位SPARC,运行Solaris 10虚拟机。 jboss 5.0.1.GA,java 1.6.0_17
我们设置了一个由2个相同的盒子组成的测试环境,运行相同的软件,但一个使用jboss 4.0.5GA,另一个使用jboss 5.0.1.GA.它们是运行在HP ProLiant DL560 Gen8上的VMWare VM,具有4 x 2.2GHz Intel Xeon CPU E5-4620和64GB RAM。来宾VM是4个vCPU,4096MB RAM,CentOS 6.4。
我们发现我们可以轻松地在我们的环境中重现这个问题。在4.0.5上运行的盒子运行正常,但在jboss 5.0.1GA上我们看到了同样奇怪的GC行为。由于我们没有与生产相同的负载量,因此无法在我们的环境中轻松测试性能。
我们认为这不是内存泄漏,因为在每个主要GC之后,使用的堆大小会返回到相同的大小:
分析在启示前后的堆转储,我们发现以下对象的数量不同:
org.jboss.virtual.plugins.context.file.FileSystemContext
除此之外,堆转储看起来非常相似,顶层对象是java或jboss对象(即没有应用程序类)
在我们的测试环境中设置-Djboss.vfs.forceVfsJar=true
修复了问题(即奇怪的GC行为消失了),但是在生产中应用时,奇怪的GC模式和性能问题仍然存在 - 尽管GC时间没有增加太多(到0.3秒而不是1.5秒)。
在我们的测试环境中,我们在jboss 5.1.0中部署了相同的软件,并发现了与5.0.1相同的行为。
因此,此时的结论是jboss 5.x在60/90分钟左右发生了一些事情,这对垃圾收集和性能都有影响。
更新
我们尝试将Web服务堆栈升级到jbossws-native-3.3.1,这解决了我们测试环境中的问题。但是,当部署到下一个测试环境(更接近生产环境)时,问题仍然存在(虽然已经减少)。
更新
我们已经通过将jboss.vfs.cache.TimedPolicyCaching.lifetime设置为相当于多年的非常大的数字来解决这个问题。
这感觉就像jboss中的一个bug的解决方法。默认缓存生存期为30分钟(请参阅org.jboss.util.TimedCachePolicy),我们在60或90分钟后看到了问题。
VFS缓存实现是CombinedVFSCache,我认为它正在使用下面的TimedVFSCache。
似乎更好的解决方法是将缓存实现更改为永久缓存,但我们已经浪费了足够的时间来解决此问题,我们的解决方法必须这样做。
答案 0 :(得分:0)
仅查看Gc图很难确定此问题的根本原因。那么当这种情况发生时,堆栈是怎么样的?有没有过度活跃的线程?是否有任何讨厌的线程创建了大量的对象迫使垃圾收集器工作,以摆脱它们?我认为必须进行更多分析以确定问题的根本原因。