问九:元空间(MetaSpace)与永久代(PermGen)的区别是什么?
两者介绍:
在JDK1.8之后,开始将类的元数据Meta信息放到本地堆内存中,这部分内存就称为元空间,这在JDK1.7及以前是属于永久代的,但是在JDK1.8之后,元空间就取代了永久代
它们两个都是用来存储class的相关信息的,比如class的method和field等
它们两个都是方法区的实现,只是实现不同,所以说方法区只是JVM的一种规范
元空间(MetaSpace)没有了字符串常量池,在JDK1.7的时候已经移动到了堆中
JDK8的变化:
* 移除了永久代(PermGen),替换为元空间(Metaspace);
* 永久代中的 class metadata 转移到了 native memory(本地内存,而不是虚拟机);
* 永久代中的 interned Strings 和 class static variables 转移到了 Java heap;
* 永久代参数 (PermSize MaxPermSize) -> 元空间参数(MetaspaceSize MaxMetaspaceSize)
两者区别:
元空间使用本地内存(native mermory),而永久代使用的是JVM的内存(好处是:java.lang.OutOfMemoryError:PermGen spce将不会存在)
元空间(MetaSpace)相比永久代(PermGen)的优势:
字符串常量池存在永久代(永久代在JDK7是方法区的一种实现)中,容易出现性能问题和内存溢出
类和方法的信息大小难以确定,给永久代的大小指定带来困难(太小,容易导致永久代溢出 太大,容易导致老年代溢出)
永久代会为GC带来不必要的复杂性
方便HotSpot与其他JVM如JRockit的集成
java的方法区在堆中吗?
三种情况:
java7之前,方法区位于永久代(PermGen),永久代和堆相互隔离,永久代的大小在启动JVM时可以设置一个固定值,不可变;
java7中,static变量从永久代移到堆中;
java8中,取消永久代,方法存放于元空间(Metaspace),元空间仍然与堆不相连,但与堆共享物理内存,逻辑上可认为在堆中