我看到了很多关于这个问题的评论——有人说是,有人说不是,而且许多答案都是模棱两可的。任何人都可以用更简单的术语描述它所在的位置吗?在一篇文章中,我什至看到有人说它与类加载器加载类的类内存共享相同的内存位置 - 这是真的吗?
5 回答
原始(可能是错误的)答案:如果要相信维基百科,它就是堆的一部分。
编辑:我已经查看了更多内容,包括 OP 在评论中引用的网站。在这项研究中,我遇到了这个 SO question,它引用了这个文档,这表明对于 Sun Java(版本 6),永久集合实际上是在堆之外。也就是说,我不是 Java 专家,以前并不了解此级别的内存管理细节。如果我的阅读是正确的,那么永久代的放置——甚至是存在——是一个 jvm 实现细节。
从黑盒的角度来看,在 Sun JVM 中,永久代不是堆的一部分,如jconsole
的文档中所述:
永久代(非堆):包含虚拟机本身的所有反射数据的池,例如类和方法对象。对于使用类数据共享的 Java VM,这一代分为只读区和读写区。
在实践中,这意味着你的-XX:MaxPermSize
内存加起来就是你-Xmx
在 JVM 进程中的内存,因为永久代不包含在堆中。
我在阅读Java Garbage Collection Basics时遇到了同样的问题,在这个教程中,作者认为永久代是堆的一部分。
但我们两者都有:
- -Xmx
- -XX:MaxPermSize
在谷歌这个问题之后,我发现这个问题Java 堆术语:年轻、年老和永久代?,答案由此得出结论:
永久代不是堆的一部分
以下是我对该主题的理解:
永久代是存储类定义的堆区域。如http://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation所示,所有类实例在永久代中都有一个对其类型类实例的“klass”引用。在运行时创建新类型时,会在永久代中为它们的类型分配新空间。
Jon Masamitsu 的博客文章中的图表显示了永久代和可以存储程序对象实例的堆中更频繁收集的部分之间的逻辑分离。永久代仍然是堆的一部分。
Permgen 已从 Java 8 中删除。现在我们有了元空间,它不是堆的一部分,也不是内部存储器的一部分。
此外,命令 -Xmx -XX:MaxPermSize 将从 Java 8 中被忽略