两者介绍:

在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),元空间仍然与堆不相连,但与堆共享物理内存,逻辑上可认为在堆中