在 JDK 7 及以前,习惯上把方法区,称为永久代。从 JDK8 开始,使用元空间取代了永久代。
JDK 8 后,元空间存放在堆外内存中。
本质上,方法区和永久代并不等价。仅是对 hotspot 而言的。《Java虚拟机规范》对如何实现方法区,不做统一要求。例如:BEAJRockit / IBM J9 中不存在永久代的概念。
现在来看,当年使用永久代,不是好的 idea。导致 Java 程序更容易 OOM(超过-XX:MaxPermSize上限)。
而到了 JDK 8,终于完全废弃了永久代的概念,改用与 JRockit、J9 一样在本地内存中实现的元空间(Metaspace)来代替。
元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代最大的区别在于:元空间不在虚拟机设置的内存中,而是使用本地内存。
永久代、元空间二者并不只是名字变了,内部结构也调整了。
根据《Java虚拟机规范》的规定,如果方法区无法满足新的内存分配需求时,将抛出 OOM 异常。