什么时候JVM抛出OutOfMemoryError

nei*_*rda 16 java garbage-collection out-of-memory

我们正在运行一个有时"冻结"的Java应用程序,因为某些线程几乎使用了所有堆.尽管JVM执行Full GC持续时间超过60秒,但应用程序永远不会因OutOfMemoryError而死亡.

我从Java文档中读到:

如果花费太多时间进行垃圾收集,吞吐量收集器将抛出内存不足的异常.例如,如果JVM花费超过总时间的98%进行垃圾收集并且正在恢复少于2%的堆,则会导致内存不足.

我想了解更多关于98%的时间意味着什么(时间框架是什么?)的信息,以及是否可以降低此值,即如果应用程序在GC中花费90%的时间而无法释放OOME超过10%的堆.

目标是确保应用程序将在OOME中死亡(而不是仅运行GC),因此我们可以在OOME上生成转储.

以下是我们使用的内存和GC设置(操作系统是Solaris):

-Xms2048m -Xmx2048m \
-Xmn512m \
-XX:PermSize=256m 
-XX:MaxPermSize=256m \
-XX:+UseParNewGC 
-XX:ParallelGCThreads=16 \
-XX:+UseConcMarkSweepGC 
-XX:+CMSParallelRemarkEnabled \
-XX:+DisableExplicitGC \
-XX:+PrintGC 
-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps \
-XX:+PrintClassHistogram \
-Xloggc:/gcmonitor.log \
-XX:+HandlePromotionFailure \
-XX:SurvivorRatio=4 
-XX:TargetSurvivorRatio=90 
-XX:MaxTenuringThreshold=10 \
-XX:+UseTLAB 
-XX:TLABSize=32k 
-XX:+ResizeTLAB \
-XX:+UseMPSS \
Run Code Online (Sandbox Code Playgroud)

Tom*_*icz 4

我想了解更多关于这 98% 时间意味着什么的信息(时间范围是多少?)

回答这个问题:超出GC开销限制表明它是1分钟。

可以降低这个值

再次查看上面提到的问题,看起来您可以使用GCTimeLimitGCHeapFreeLimit参数。