Permgen是否是堆的一部分?
我从官方oracle网站上找到了图片
但在流行的答案中,我发现永久代不是堆的一部分
永久生成(非堆):包含虚拟机本身的所有反射数据(例如类和方法对象)的池。 对于使用类数据共享的Java虚拟机,这一代分为只读和读写区域。
我搞砸了这些矛盾的数据。 我相信这两个地方的数据都是有效的,但有保留。 请为我澄清这个问题。
PS
让我们只讲Sun / Oracle jvms。
PS2
我已经阅读了jvm gcs(serial,parallel,cms和g1)的解释,并且我没有看到关于permgen的提及,认为永久代不是heap部分。
我相信你是指这里的图表,关于Oracle的官方网站,是的他们引用了“永久代”作为堆区,但我的意图只是试图解释JVM内存中的“世代”; 但据我所知(我猜很多专家会同意它) “永久代”不是堆区域的一部分,它是JVM用于内部目的的非堆区域的一部分,如JIT优化,方法区域等 。
Oracle官方参考资料
我想引用3个官方Oracle参考资料,以帮助您确信“永久代”不是堆区的一部分。
在上面的第一个链接中,可以清楚地看到,它解释了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中已被删除(发行说明)。 删除我有以下几个原因我知道:
自Java 8以来,发生在permgen中的内存对象被放置到metaspace。Metaspace是可调整大小的内存区域,并被放入堆中。
链接地址: http://www.djcxy.com/p/82883.html