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

时间:2012-11-20 00:57:37

标签: java heap heap-memory permgen

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

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

3 个答案:

答案 0 :(得分:14)

PermGen将在JDK8中消失。

  

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

没有耗尽资源。

  

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

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

答案 1 :(得分:12)

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

然而,理由可能更多:

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

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

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

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

答案 2 :(得分:3)

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

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

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