6

我将我的 java 应用程序配置为使用 5G 内存。我突然出现了 OutOfMemory。我查看了 gc 日志,发现还有很多内存:young generation 占用了 4% 的分配空间,tenure generation 占用率为 5%,perm generation 为 43%。我很困惑为什么 JVM 在 gc 时会抛出 OutOfMemory。有谁知道为什么会这样?非常感谢您的帮助。

JVM内存和gc设置:

-server -Xms5g -Xmx5g -Xss256k -XX:NewSize=2g -XX:MaxNewSize=2g -XX:+UseParallelOldGC -XX:+UseTLAB -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:+DisableExplicitGC

gc日志

2009-09-19T03:34:59.741+0000:92836.778:[GC
所需的幸存者大小 152567808 字节,新阈值 1(最大 15)
 [PSYoungGen: 1941492K->144057K(1947072K)] 3138022K->1340830K(5092800K), 0.1947640 secs] [Times: user=0.61 sys=0.01, real=0.19 secs]
2009-09-19T03:35:29.918+0000:92866.954:[GC
所需的幸存者大小 152109056 字节,新阈值 1(最大 15)
 [PSYoungGen: 1941625K->144049K(1948608K)] 3138398K->1341080K(5094336K), 0.1942000 secs] [Times: user=0.61 sys=0.01, real=0.20 secs]
2009-09-19T03:35:56.883+0000:92893.920:[GC
所需的幸存者大小 156565504 字节,新阈值 1(最大 15)
 [PSYoungGen: 1567994K->115427K(1915072K)] 2765026K->1312820K(5060800K), 0.1586320 secs] [Times: user=0.50 sys=0.01, real=0.16 secs]
2009-09-19T03:35:57.042+0000:92894.079:[GC
所需的幸存者大小 179961856 字节,新阈值 1(最大 15)
 [PSYoungGen: 115427K->0K(1898560K)] 1312820K->1313987K(5044288K), 0.0775650 secs] [Times: user=0.42 sys=0.19, real=0.08 secs]
2009-09-19T03:35:57.120+0000:92894.157:[完整 GC [PSYoungGen:0K->0K(1898560K)][ParOldGen:1313987K->159522K(3145728K)]1313987K->159522PSPermGen:24) ->19942K(40256K)], 0.56923
00 秒] [时间:用户=2.18 系统=0.05,实际=0.57 秒]
2009-09-19T03:35:57.690+0000:92894.726:[GC
所需的幸存者大小 197066752 字节,新阈值 1(最大 15)
 [PSYoungGen: 0K->0K(1745728K)] 159522K->159522K(4891456K), 0.0072590 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
2009-09-19T03:35:57.698+0000: 92894.734: [完整 GC [PSYoungGen: 0K->0K(1745728K)] [ParOldGen: 159522K->158627K(3145728K)] 159522K->158627K->158627K(Gen:19594) ->19934K(45504K)], 0.3280480
 秒] [时间:用户=1.46 系统=0.00,真实=0.33 秒]
堆
 PSYoungGen 总计 1745728K,已使用 87233K [0x00002aab73650000, 0x00002aabf3650000, 0x00002aabf3650000)
  伊甸园空间 1745664K,已使用 4% [0x00002aab73650000,0x00002aab78b80778,0x00002aabddf10000)
  从空间 64K,使用 0% [0x00002aabddf10000,0x00002aabddf10000,0x00002aabddf20000)
  到空间 192448K,使用 0% [0x00002aabe7a60000,0x00002aabe7a60000,0x00002aabf3650000)
 ParOldGen 总计 3145728K,已使用 158627K [0x00002aaab3650000, 0x00002aab73650000, 0x00002aab73650000)
  对象空间 3145728K,已使用 5% [0x00002aaab3650000,0x00002aaabd138d28,0x00002aab73650000)
 PSPermGen 总计 45504K,使用了 19965K [0x00002aaaae250000, 0x00002aaab0ec0000, 0x00002aaab3650000)
  对象空间 45504K,已使用 43% [0x00002aaaae250000,0x00002aaaaf5cf668,0x00002aaab0ec0000)

我在 64 位 Linux 和 JRE 1.6.0_10 上:

$uname -a
Linux x 2.6.24-etchnhalf.1-amd64 #1 SMP Tue Oct 14 03:11:45 UTC 2008 x86_64 GNU/Linux 

$java -version
java version "1.6.0_10" 
Java(TM) SE Runtime Environment (build 1.6.0_10-b33) 
Java HotSpot(TM) 64-Bit Server VM (build 11.0-b15, mixed mode)
4

3 回答 3

3

好吧,这可能是一个愚蠢的答案,但你的盒子确实有至少 5GB 的 RAM,对吧?只是检查。:-) 我不记得JVM是否真的检查你是否真的有足够的内存,直到它实际尝试分配它。

于 2009-09-22T14:13:44.233 回答
0

此外,OutOfMemoryException 的详细信息是什么 - 它与 GC 开销限制有关吗?如果是这样,可以禁用该异常(-XX:-UseGCOverheadLimit)

请参阅此页面关于gc 选项及其解释

于 2009-09-20T20:27:49.960 回答
0

您可能需要考虑使用分析器和调试器来了解发生内存不足错误的确切状态。

我使用 Jprofiler 进行分析,使用 Eclipse 的 Debugger 进行调试。两者都具有足够的功能来满足其目的。

我还希望看到错误的堆栈跟踪,以识别错误的种类以及它到底从哪里开始。这是问题中缺少的非常重要的信息。

于 2010-08-01T07:14:23.413 回答