2

我有一个在启动时运行两个或三个完整 GC 的应用程序。有很多堆空间,不需要运行任何 GC(次要或完全)。但是在 gc 日志中,我可以看到 permgen 被填满,然后立即运行完整的 GC。在此之后,permgen 空间增加。最终,一旦加载了所有类,就不再有完整的 GC。

我的问题是,如果 permgen 被填满,VM 是否会运行 GC 以从堆中获取一些内存并为 permgen 添加额外的内存?还是会抛出 OutOfMemory-permgen?

4

2 回答 2

3

我的问题是,如果 permgen 被填满,VM 是否会运行 GC 以从堆中获取一些内存并为 permgen 添加额外的内存?还是会抛出 OutOfMemory-permgen?

GC 将运行完整的 GC 以尝试释放 permgen 空间中的一些内存。如果这未能释放足够的空间,则会抛出 OOME,说 permgen 已满。

当前或过去的 HotSpot JVM 不会尝试将 permgen 增加到超出其规定的限制,无论是否有正常的堆空间允许这样做。


在 OOME (permgen) 之前需要进行完整 GC 的原因是:

  • 在非 permgen 空间中可能已经引用了 permgen 对象。运行一个完整的 GC 来检查这个。
  • (AFAIK)GC'ing permgen 通常与完整的 GC 相关联......大概是出于同样的原因。它通常是来自普通堆和 GC“根”的引用,它们使 permgen 对象保持可访问性。

Permgen 对象(AFAIK)通常是不可变的,因此不太可能由于 permgen 对象突变而改变可达性。

于 2013-04-09T05:36:22.143 回答
0

如果 PermGen 大小达到您的 -XX:MaxPermGen 限制(或默认值),它将抛出 OOM-permgen。

于 2013-04-09T04:59:25.083 回答