以下是我的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(堆的23)新一代:600MB(堆的13)
Old Gen在内存中的增长超过70% 0f其分配的大小,即使在100%即1.4GB.可以看到下面的图表,它的峰值,从来没有GC,内存的下降是当它被强制GC从JConsole.这个问题最终使Web服务器下降。
有什么地方是我遗漏的或者JVM设置错误的吗?
先谢谢大家的帮助。
更新我的问题。
经过堆分析,似乎Stateful session bean是主要嫌疑人。我们有一个有状态的session bean,它在Hibernate的帮助下保持着持久化逻辑。
GC最终会被调用,旧基因几乎不会被调用(因为它非常慢).GC确实会运行,但它一开始只会在新基因和幸存者基因上运行,它有一个完全不同的算法来清理旧基因,这比newsurvivor基因更慢。
这些数字真的很高,与新基因相比,旧基因不应该达到这么高的总和,我猜你有一个内存泄漏。
我只能猜测你的程序在处理大文件,你可能是保存引用的时间太长了。
即使主要的问题(内存泄漏)已经解决了,如果你仍然希望在频繁的小规模停顿中清除旧的gen,你可以尝试设置为
-XX:MaxGCPauseMillis=(time in millis)
而这只适用于并行收集器,并且当自适应大小策略开启时。默认情况下,自适应大小策略是开启的,但是,如果您想明确地提到这一点,您可以使用。
-XX:+UseAdaptiveSizePolicy
或者,您可以切换到CMS收集器,在那里您可以使用 "自适应大小策略"。
-XX:CMSInitiatingOccupancyFraction=(% value)
-XX:+UseCMSInitiatingOccupancyOnly
当旧基因达到一定的比例时,哪种收集旧基因的方式更可靠。
有状态的session beans让JVM耗尽了内存.使用@Remove注解显式处理它们解决了这个问题。