【问题标题】:Why is the default size of PermGen so small?为什么 PermGen 的默认大小这么小?
【发布时间】:2012-11-08 00:57:30
【问题描述】:

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

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

【问题讨论】:

  • 作为一名 Java SE 程序,我在 13 年的 Java 编程中从未达到 PermGen 的限制。很可能就是这种把极限保持在低位的想法。即忘记有些人经常打它。 ;) 注意:在 Java 7 中,字符串字面量池位于堆中,而不是 PermGen。

标签: java heap-memory permgen


【解决方案1】:

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

您宁愿为应用程序数据(XmsXmx,其中 young(短期)和 分配内存到 Java 堆>tenured 对象消失(当 JVM 意识到它们需要停留更长时间时))。

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

【讨论】:

    【解决方案2】:

    PermGen 在 JDK8 中被设置为消失。

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

    不会耗尽资源。

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

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

    【讨论】:

    • 有趣。您的评论启发我研究 JDK8 背后的原因以及使用 MaxMetaspaceSize 而不是 MaxPermGen。谢谢。 :-)
    【解决方案3】:

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

    但是,原因可能更多:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-11-23
      • 2012-08-05
      • 2015-02-13
      • 1970-01-01
      • 2011-03-09
      • 2014-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多