以下是我的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辅助的持久性逻辑。
答案 0 :(得分:6)
最终将调用GC,旧的gen几乎从不被调用(因为它非常慢)。 GC确实运行但它最初只运行在新的gen和幸存者的基础上,它有一个完全不同的清除旧的算法,比新的/幸存者gens慢。
这些数字真的很高,与newgen相比,oldgen永远不会达到一个很高的数字。 我的猜测是你有内存泄漏。
我只能猜测你的程序正在处理大文件,你可能会长时间保存对它们的引用。
答案 1 :(得分:3)
有状态会话bean使JVM内存不足。 使用@Remove注释显式处理它们解决了这个问题。
答案 2 :(得分:3)
即使仍然遇到主要问题(内存泄漏),如果您仍然希望在频繁的小型暂停中清除旧版本,您可以尝试设置
-XX:MaxGCPauseMillis=(time in millis)
这仅适用于Parallel Collector以及启用自适应调整策略时。默认情况下,自适应调整策略已启用,但是,如果您想明确提及此功能,则可以使用。
-XX:+UseAdaptiveSizePolicy
否则您可以切换到CMS收集器,您可以使用
-XX:CMSInitiatingOccupancyFraction=(% value)
-XX:+UseCMSInitiatingOccupancyOnly
当它已经达到老一代的某一部分时,这是一种更可靠的收集旧种族的方式。