我在官方的甲骨文网站上找到了照片

但是在流行的所以回答中,我发现永久世代不是堆的一部分
永久生成(非堆):包含虚拟机本身的所有反射数据的池,例如类和方法对象。通过使用类数据共享的Java,这一代被划分为只读和读写区域。
我把这些矛盾的数据搞砸了。我相信,在这两个地方的数据是有效的,但有保留。请为我澄清这个问题。
附注:
让我们只谈Sun/Oracle jvms。
P.S.2
我读过关于jvm (串行、并行、cms和g1)的解释,也没有看到对permgen it论点的提及,即永久生成不是堆部分。
发布于 2016-12-31 15:22:50
我相信您是在引用这里官方站点的图表,是的,他们引用“永久代”作为堆区域,但我猜意图只是试图解释JVM内存中的“世代”;但据我所知(我猜许多专家都会同意),“永久生成”不是堆区域的一部分,它是JVM用于内部目的(如JIT优化、方法区域等)的非堆区域的一部分。
Oracle官方参考资料
我想引用下面三个官方Oracle引用,以帮助您确信“永久代”不是堆区域的一部分。
在上面的第一个链接中,您可以清楚地看到,管理2种内存-堆和非堆内存,然后它们列出了每种类型内存中的“代”。您可以在链接“监视内存消耗”中阅读本节,下面是一些摘录。


然后在上面的第二个链接中,GC开发人员非常好地解释了“永久代”的目的和见解,可以清楚地理解“永久生成”不是堆区,参见下面的博客图表:

然后,在上面的的第三个链接中,您可以引用第3.2节“度量”中所做的内存测量,这也清楚地表明“永久生成”不是堆区域的一部分。
另外,您还知道,在“终身代”中完成GC之后,在最坏的情况下,JVM会抛出内存异常,但不会将对象提升为“永久生成”,因为它不是堆区域的一部分。
非Oracle引用
查看下面的图表,可以找到许多这样的图表,这说明了JVM的内存调优参数。如果您也从内存调优JVM参数透视图中看到,那么“永久生成”并不是堆区域的一部分,这也是不言而喻的。

最后
现在,我认为应该清楚的是,图表(及其文章)仅仅是从“世代”的角度解释JVM内存概念,但是在实现中,JVM并不认为“永久生成”是堆内存的一部分,在堆内存中它可以促进长寿对象。
发布于 2016-12-28 09:35:50
Java8没有PermGen,但是MetaSpace提供了相同的功能,工作原理相似,但没有相同的功能。
Java 7有一个<=,虽然它是一个,但它不是分配对象的相同堆吗?它不计算最大堆大小,也不计算CompressOops可寻址的32 GB限制。作为垃圾收集的一部分,它被清理干净。
在相同的图表中使用它是有意义的,但这并不意味着PermGen/MetaSpace是同一个堆的一部分。
还请注意,当堆空间耗尽时,您将得到
java.lang.OutOfMemoryError: Heap space space但是,当PermGen用完时,您会得到一个不同的错误。
java.lang.OutOfMemoryError: PermGen spacehttps://plumbr.eu/outofmemoryerror/java-heap-space
发布于 2016-12-28 09:20:52
Permgen是Java 7和更早版本中固定大小的内存区域。它已在Java8 (发布说明)中删除。我知道移除的原因有以下几点:
从Java8开始,发生在permgen中的内存对象被放置到梅斯帕斯。Metaspace是可调整大小的内存区域,并被放置到堆中。
https://stackoverflow.com/questions/41358895
复制相似问题