JVM究竟在什么时候抛出一个OutOfMemoryError
2022-09-03 07:54:51
我们正在运行一个Java应用程序,它有时会“冻结”,因为某些线程几乎使用了所有的堆。尽管JVM执行的Full GC持续超过60秒,但应用程序永远不会因OutOfMemoryError而死亡。
我从Java文档中读到:
如果执行垃圾回收花费的时间过多,吞吐量收集器将引发内存不足异常。例如,如果 JVM 花费的总时间超过 98% 的时间进行垃圾回收,并且恢复的堆少于 2%,则它将引发内存不足的预期。
我想了解更多关于这98%的时间意味着什么的信息(时间框架是什么?),以及是否有可能降低这个值,即如果应用程序在GC中花费了90%的时间并且无法释放超过10%的堆,则抛出一个OOME。
目标是确保应用程序将使用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 \