Permgen是否是堆的一部分?

我从官方oracle网站上找到了图片

但在流行的答案中,我发现永久代不是堆的一部分

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

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

PS

让我们只讲Sun / Oracle jvms。

PS2

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


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

Oracle官方参考资料

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

  • Oracle的jConsole指南。
  • Oracle GC开发人员的博客。
  • Oracle关于GC调优的文章
  • 在上面的第一个链接中,可以清楚地看到,它解释了Java管理两种内存 - 堆和非堆内存 ,然后他们列出了存在于每种内存中的“世代”。 您可以在“监视内存消耗”链接中阅读本节,以下是一些摘录。

    在这里输入图像描述在这里输入图像描述

    然后在上面的第二个链接中 ,GC开发人员很好地解释了“永久代”的目的和洞察力,通过它可以清楚地理解“永久代”不是堆区,从博客的下图中可以看出:

    在这里输入图像描述

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

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

    非Oracle参考

    在下面的结构图中,可以找到许多这样的图解释JVM的内存调整参数。 如果你从内存中看到调优JVM参数的观点,那么不言而喻,“永久代”不是堆区的一部分。

    在这里输入图像描述

    到底

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


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

    Java <= 7有一个PermGen,虽然它是一个Java托管空间,但它与分配对象的堆不同。它不会计入最大堆大小,也不会计算CompressOops可寻址的32 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


    Permgen是Java 7和更早版本中固定大小的内存区域。 它在Java 8中已被删除(发行说明)。 删除我有以下几个原因我知道:

  • 合并的热点和jrockit
  • 'java.lang.OutOfMemoryError:PermGen space'出现在做字节码生成的应用程序中
  • 自Java 8以来,发生在permgen中的内存对象被放置到metaspace。Metaspace是可调整大小的内存区域,并被放入堆中。

    链接地址: http://www.djcxy.com/p/82883.html

    上一篇: Permgen is part of heap or not?

    下一篇: Clarification on stack & heap