Permgen是不是堆的一部分?

时间:2016-12-28 09:18:13

标签: java garbage-collection heap-memory

我从官方oracle网站enter image description here

找到了图片

但是在流行的SO answer中我发现永久生成不是堆

的一部分
  

永久生成(非堆):包含所有内容的池   虚拟机本身的反射数据,如类和   方法对象。对于使用类数据共享的Java VM,这个   生成分为只读和读写区域。

我搞砸了这些矛盾的数据。我相信在这两个地方数据有效但有保留。请为我澄清这个问题。

P.S。

我只谈谈Sun / Oracle jvms。

P.S.2

我已经阅读了jvm gcs(serial,parallel,cms和g1)的解释,我没有看到关于permgen的提及,它认为永久生成不是堆部分。

3 个答案:

答案 0 :(得分:4)

我相信你引用了来自here的关于甲骨文官方网站的图表,是的,他们引用了“永久代”作为堆区域,但我想这只是试图解释JVM内存中的“世代” ;但据我所知(我猜很多专家会同意)“永久生成”不是堆区域的一部分,它是非堆区域的一部分,JVM用于内部目的,如JIT优化,方法领域等

Oracle官方参考

我想在下面引用3个官方Oracle参考资料,以帮助您确信“永久生成”不是堆区域的一部分。

  1. jConsole guide from Oracle
  2. Blog of a Oracle GC developer
  3. Oracle article on GC tuning
  4. 在上面的第一个链接中,您可以清楚地看到Java解释了Java管理2种内存 - 堆和非堆内存,然后它们列出了每个内存中的“代”记忆的类型。您可以在“监视内存消耗”链接中阅读本节,下面是一些摘录。

    enter image description here enter image description here

    然后在上面的第二个链接中,GC开发人员已经很好地解释了“永久代”的目的和洞察力,使用它可以清楚地理解“永久代”不是一堆区域,请参阅博客中的下图:

    enter image description here

    然后在上面的第三个链接中,您可以参考第3.2节“测量”中完成的内存测量,这也清楚地表明“永久生成”不是堆区域的一部分。 / p>

    另外,你会知道在“Tenured generation”中完整的GC之后,在最坏的情况下,JVM会抛出内存异常但不会将对象提升为“永久生成”,因为它不是堆区域的一部分。 / p>

    非Oracle引用

    检查下图,可以找到许多这样的图解释JVM的内存调整参数。如果从内存调整JVM参数的角度看也是如此,那么“永久生成”不是堆区域的一部分也是不言而喻的。

    enter image description here

    最后

    现在,我认为你应该清楚,图(及其文章)只是为了从“世代”角度解释JVM内存概念,但在实现中JVM并不认为“永久代”是堆内存的一部分,它可以促进长寿命对象。

答案 1 :(得分:1)

Java 8没有PermGen,但是MetaSpace提供了相同的功能并且工作方式相似但不相同。

Java< = 7有一个PermGen,虽然它是一个Java托管空间,但它不是分配对象的堆。它不计入最大堆大小,也不计入32例如,CompressOops可以寻址的GB限制。它被清理为垃圾收集的一部分。

将它放在同一个图表中是有意义的,但它并不意味着PermGen / MetaSpace是同一堆的一部分。

另请注意,当堆空间用完时,您将获得

java.lang.OutOfMemoryError: Heap space space

然而,当你用完PermGen时,你会得到一个不同的错误。

java.lang.OutOfMemoryError: PermGen space

https://plumbr.eu/outofmemoryerror/java-heap-space

https://plumbr.eu/outofmemoryerror/permgen-space

https://plumbr.eu/outofmemoryerror/metaspace

答案 2 :(得分:0)

Permgen是Java 7及更早版本中固定大小的内存区域。它已在Java 8中删除(release notes)。删除后我有以下原因:

  1. hotshot和jrockit的合并
  2. 'java.lang.OutOfMemoryError:PermGen space'出现在执行字节码生成的应用程序中
  3. 自Java 8以来,发生在permgen中的内存对象被置于metaspace。元数据空间是可调整大小的内存区域并被放入堆中。