【问题标题】:PermGen thrashing at 99%, but nowhere near MaxPermSizePermGen 以 99% 的速度颠簸,但远不及 MaxPermSize
【发布时间】:2014-12-02 03:41:59
【问题描述】:

我有一个可重复的情况,即 JVM 正在承受繁重的 GC 负载。当我使用 jmap -heap 请求 JVM 统计信息时,我得到以下信息(来自 Linux 上的 Oracle JDK 1.7.0_25)

请注意,虽然它说MaxPermSize 是 256m,但它还说 PermGen 是 136MB,但容量为 99.9%。

这可以解释 GC 颠簸,但我的问题是为什么 JVM 不将 PermGen 扩展到完全可用的 256m?是否有一些参数可以防止池扩展发生,并阻止 JVM 充分利用这 256m?

请注意,Tenured 池也变得有点紧张,但远不及 permgen。

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio = 5
   MaxHeapFreeRatio = 10
   MaxHeapSize      = 805306368 (768.0MB)
   NewSize          = 1048576 (1.0MB)
   MaxNewSize       = 4294901760 (4095.9375MB)
   OldSize          = 4194304 (4.0MB)
   NewRatio         = 8
   SurvivorRatio    = 8
   PermSize         = 50331648 (48.0MB)
   MaxPermSize      = 268435456 (256.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 43909120 (41.875MB)
   used     = 495240 (0.47229766845703125MB)
   free     = 43413880 (41.40270233154297MB)
   1.1278750291511195% used
Eden Space:
   capacity = 39059456 (37.25MB)
   used     = 495240 (0.47229766845703125MB)
   free     = 38564216 (36.77770233154297MB)
   1.2679132039114933% used
From Space:
   capacity = 4849664 (4.625MB)
   used     = 0 (0.0MB)
   free     = 4849664 (4.625MB)
   0.0% used
To Space:
   capacity = 4849664 (4.625MB)
   used     = 0 (0.0MB)
   free     = 4849664 (4.625MB)
   0.0% used
tenured generation:
   capacity = 389492736 (371.44921875MB)
   used     = 350542912 (334.30377197265625MB)
   free     = 38949824 (37.14544677734375MB)
   89.99985868799361% used
Perm Generation:
   capacity = 143392768 (136.75MB)
   used     = 143338624 (136.6983642578125MB)
   free     = 54144 (0.0516357421875MB)
   99.96224077353747% used

174149 interned Strings occupying 19526656 bytes.

【问题讨论】:

  • Mark Sweep Compact 算法没有过度扩展 Perm 空间的意义。 JVM 会根据实际需要分配尽可能多的内存。那没问题。我建议你描述真正的问题。
  • 我也有同样的问题。 PermSize=20.75MB, MaxPermSize=256.0MB 但仍然“PS Perm Generation”几乎已满,容量为 136.0MB,已使用 130MB。有很多可用的操作系统内存(> 2GB)。我不明白。

标签: java garbage-collection jvm


【解决方案1】:

一个可能的原因是您的计算机没有更多可用内存,因此 JVM 无法为 PermGen 分配更多空间(您需要比配置的内存多 30% 的可用内存)。

其他原因(我更喜欢这个)是 Java 人体工程学的一种奇怪行为。您的 JVM 可能决定您的 PermGen“最佳大小”为 136MB,但在某些时候未能增加它。可能是因为您的 PermGen 导致的内存泄漏。如果你使用 Concurrent Mark and Sweep GC,你可以尝试使用-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled。

【讨论】:

  • 如果系统没有足够的内存来扩展堆大小(堆的任何部分),它将导致JVM终止,以防HotSpot JVM。
【解决方案2】:

系统总内存是多少?它是 32 位还是 64 位 jvm? 就主要问题而言(如上所述) - JVM 尝试分配 PermGen 空间(在定义的范围内),但当系统内存不可用时会引发 OOM 错误。

但我不同意 Alexey Ragozin - 如果 MaxPermGen Size 低于所需,则 JVM 将停止并抛出 Perm Gen Space 错误 - 无论主机或堆的其他部分有多少可用内存 [Eden / Tenured]。

【讨论】:

    猜你喜欢
    • 2015-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    相关资源
    最近更新 更多