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

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

如果我的应用程序使用85MB的permgen,那么将它设置为96MB可能是安全的,但为什么如果它只是主堆的真正部分呢? 允许JVM在堆允许的情况下使用尽可能多的PermGen会不会有效?

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

但是,理由可能更多:

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

因此,当我看到事物时,大多数时候分配永久“代”的原因实际上是出于实际的实现原因而不是因为程序员真的非常关心。

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

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

PermGen将在JDK8中消失。

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

没有耗尽资源。

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

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

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

您宁愿为Java应用程序数据分配内存( XmsXmx ,其中年轻 (短期)和终身对象(当JVM意识到它们需要保持更长时间时))。

因此,历史性的PermGen 64MB默认值可能是任意的,但是如果明确设置它,则可以让您了解(并控制)应用程序导致JVM存储的静态数据量。