以下是我的JVM设置:
JAVA_OPTS=-server -Xms2G -Xmx2G -XX:MaxPermSize=512M -Dsun.rmi.dgc.client.gcInterval=1200000 -Dsun.rmi.dgc.server.gcInterval=1200000 -XX:+UseParallelOldGC -XX:ParallelGCThreads=2 -XX:+UseCompressedOops -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jbos88,server=y,suspend=n
问题:总堆内存:2GB旧代:1.4GB(2/3堆)新代:600MB(1/3堆)
Old Gen的内存增长超过其分配大小的70%,即使在100%即1.4GB时也不会受到GC的影响。可以看到它下面的图表达到峰值并且从不是GC,内存的下降是从JConsole强制进入GC的时候。这个问题最终导致Web服务器崩溃。
我缺少什么或错误地设置JVM?
我在这里先向您的帮助表示感谢。
更新我的问题:
在堆分析之后,似乎有状态会话bean是主要的嫌疑人:我们有状态会话bean,其中包含Hibernate辅助的持久性逻辑。
最终将调用GC,旧的gen几乎从未被调用(因为它非常慢)。 GC确实运行但它最初只运行在新的gen和幸存者的基础上,它有一个完全不同的清除旧的算法,比新的/幸存者gens慢。
这些数字真的很高,与newgen相比,oldgen永远不会达到很高的数字。我的猜测是你有内存泄漏。
我只能猜测你的程序正在处理大文件,你可能会长时间保存对它们的引用。
即使仍有主要问题(内存泄漏)已解决,如果您仍希望在频繁的小尺寸暂停中清除旧版本,您可以尝试设置
-XX:MaxGCPauseMillis=(time in millis)
这仅适用于Parallel Collector并且启用了自适应调整策略。默认情况下,自适应调整策略已启用,但是,如果您想明确提及此功能,则可以使用。
-XX:+UseAdaptiveSizePolicy
或者您可以切换到可以使用的CMS收集器
-XX:CMSInitiatingOccupancyFraction=(% value)
-XX:+UseCMSInitiatingOccupancyOnly
当它已经达到老一代的某一部分时,这是一种更可靠的收集旧的方式。
有状态会话bean使JVM内存不足。使用@Remove注释显式处理它们解决了这个问题。