为什么 PermGen 的默认大小如此之小?

2022-09-02 20:49:18

限制 Java JVM 上 Permgen 空间大小的目的是什么?为什么不始终将其设置为等于最大堆大小?为什么Java默认为如此小的64MB?他们是否试图通过这样做来迫使人们注意到代码中的permgen问题?

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


答案 1

PermGen在JDK8中将被设置为消失。

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

不耗尽资源。

为什么不始终将其设置为等于最大堆大小?

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


答案 2

从概念上讲,对于程序员来说,你可以说“永久的一代”在很大程度上是毫无意义的。如果您需要加载类或其他“永久”数据,并且还剩下内存空间,那么原则上您不妨将其加载到某个地方,而根本不关心将这些项的聚合称为“生成”。

但是,基本原理可能更多是:

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

因此,在我看来,大多数时候分配永久“世代”的原因实际上是出于实际的实现原因,而不是因为程序员真的非常在乎。

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

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


推荐