堆内存使用中的 PS Old Gen 内存:Java 内存不足异常的 GC 设置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25818068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PS Old Gen memory in Heap Memory Usage: GC settings for Java Out Of Memory Exception
提问by amitsalyan
Below are my JVM settings:
以下是我的 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
Problem: Total Heap Memory: 2GB Old Gen: 1.4GB (2/3 of Heap) New Gen: 600MB(1/3 of Heap)
问题:总堆内存:2GB 老一代:1.4GB(堆的 2/3) 新一代:600MB(堆的 1/3)
The Old Gen grows in memory beyond 70% 0f its allocated size and never is subjected to GC even at 100% i.e 1.4GB. One can see the graph below it peaks and never is GC, the drop in memory is when it was forced to GC from the JConsole. This problem is eventually bringing the web server down.
Old Gen 的内存增长超过其分配大小的 70% 0f,并且即使在 100% 即 1.4GB 时也不会进行 GC。可以看到下面的图表达到峰值并且从来没有 GC,内存下降是当它被迫从 JConsole 进行 GC 时。这个问题最终会导致 Web 服务器宕机。
Anything that i am missing or wrongly setting the JVM?
我遗漏或错误地设置了 JVM 的任何内容?
Thanks for the help in advance.
我在这里先向您的帮助表示感谢。
Updating my Question:
更新我的问题:
After heap analysis it appears like Stateful session bean is the prime suspect:
We have stateful session beans that hold the persistence logic assisted by Hibernate.
经过堆分析,似乎有状态会话 bean 是主要嫌疑人:
我们有有状态会话 bean,它包含由 Hibernate 辅助的持久性逻辑。
采纳答案by amitsalyan
The stateful session beans were making the JVM run out of memory.
Explicitly handling them using @Remove annotation resolved this issue.
有状态会话 bean 导致 JVM 内存不足。使用 @Remove 注释显式处理它们解决了这个问题。
回答by David Limkys
The GC will be called eventually, the old gen is almost never called (because it is extremely slow). The GC does run but it will only run on the new gen and survivor gen at first, it has a completely different algorithm for cleaning the old gen which is slower then new/survivor gens.
GC 最终会被调用,老 gen 几乎从不调用(因为它非常慢)。GC 确实会运行,但它最初只会在新代和幸存者代上运行,它具有完全不同的算法来清理旧代,该算法比新/幸存者代慢。
Those numbers are really high, the oldgen should never reach sum a high number compared to the newgen. My guess is that you have a memory leak.
这些数字真的很高,与 newgen 相比,oldgen 不应该达到总和。我的猜测是你有内存泄漏。
I can only guess your program is dealing with big files, you are probably saving references to them for too long.
我只能猜测你的程序正在处理大文件,你可能保存对它们的引用太久了。
回答by Tharanga Hewavithana
Even still having the main problem (memory leak) resolved, if you still want the old gen to be cleared in frequent small sized pauses, you may try setting
即使仍然解决了主要问题(内存泄漏),如果您仍然希望在频繁的小暂停中清除旧代,您可以尝试设置
-XX:MaxGCPauseMillis=(time in millis)
and this is only applicable with Parallel Collector and when Adaptive Sizing Policy is on. By default Adaptive Sizing Policy is on, but, if you want to explicitly mention this you can use.
并且这仅适用于 Parallel Collector 并且启用了自适应大小调整策略时。默认情况下 Adaptive Sizing Policy 处于开启状态,但是,如果您想明确提及这一点,您可以使用。
-XX:+UseAdaptiveSizePolicy
Or else you can switch to CMS collector where you can use
或者你可以切换到 CMS 收集器,在那里你可以使用
-XX:CMSInitiatingOccupancyFraction=(% value)
-XX:+UseCMSInitiatingOccupancyOnly
Which is a more reliable way of collecting the old gen when it has reached a certain fraction of the the old gen.
当旧基因达到一定比例时,这是一种更可靠的收集旧基因的方法。