18

限制 Java JVM 上 Permgen 空间大小的目的是什么?为什么不总是将它设置为等于最大堆大小?为什么Java默认为64MB这么少?他们是否试图通过这样做来强迫人们注意到他们代码中的永久问题?

如果我的应用程序使用 85MB 的 permgen,那么将其设置为 96MB 可能是安全的,但如果它只是主堆的一部分,为什么要设置这么小呢?允许 JVM 使用堆允许的尽可能多的 PermGen 不是很有效吗?

4

3 回答 3

14

PermGen 将在 JDK8 中消失。

限制 Java JVM 上 Permgen 空间大小的目的是什么?

不消耗资源。

为什么不总是将它设置为等于最大堆大小?

PermGen不是Java 堆的一部分。此外,即使是这样,用类元数据和常量字符串填充堆对应用程序也没有多大帮助,因为你会得到“OutOfMemoryError: Java heap size”错误。

于 2012-11-20T01:16:07.730 回答
13

从概念上讲,对于程序员来说,您可能会争辩说“永久一代”在很大程度上是没有意义的。如果您需要加载一个类或其他“永久”数据并且有剩余的内存空间,那么原则上您最好将它加载到某个地方,而不关心将这些项目的聚合称为“一代”。

然而,理由可能更多的是:

  • 将所有代码/类元数据放在内存空间中附近可能有好处(例如,从处理器缓存的角度来看),并且为了保证这一点,更容易分配固定大小的区域;
  • 同样,存储代码/类元数据的内存空间可能具有某些“特殊”属性(特别是,如果您能提供帮助,您不希望它被分页到磁盘)并且系统可能无法设置此类属性以非常细化的方式在内存上,因此将所有“特殊”对象放在一个(或少数)连续块或内存空间中更为实用;
  • 将永久对象放在一起有助于避免分割剩余的内存空间,最实用的方法是从一开始就分配一个固定大小的连续内存块。

所以正如我所看到的,大多数时候分配永久“代”的原因实际上是出于实际实施原因,而不是因为程序员真的非常关心。

另一方面,对于程序员来说,情况通常也不可怕:所需的永久代数量通常是可预测的,因此您应该能够以适当的余地分配所需的数量。因此,如果您发现自己意外超出了分​​配,这很可能是“严重错误”的信号。

注意 可能 PermGen 最初旨在解决的一些问题在具有更大处理器缓存的现代 64 位处理器上并不是那么大的问题。如果它在 Java 的未来版本中被删除,这可能表明 JVM 设计者认为它现在已经“达到了它的目的”。

于 2012-11-20T01:15:44.537 回答
3

PermGen 是分配数据和其他静态内容(如字符串文字)的地方。

您宁愿为您的应用程序数据分配内存到Java堆(Xms并且Xmx年轻(短期)和终身对象所在的位置(当 JVM 意识到它们需要停留更长时间时))。

因此,历史上的 PermGen 64MB 默认值可能是任意的,但是明确设置它可以让您知道(并控制)您的应用程序导致 JVM 存储多少静态数据。

于 2012-11-20T01:25:11.760 回答