定义
方法区是Java虚拟机规范定义的一块用于存储类信息、常量、静态变量、编译器编译后的代码等数据的内存区域。方法区是规范,不是实现。
JDK1.6
方法区被实现为永久代
运行时数据区如图:

JDK1.7
在1.7中,把字符串常量池、和静态变量都移到了堆内存中,主要原因是因为永久代的 GC 回收效率太低,只有在FullGC的时候才会被执行回收,但是Java中往往会有很多字符串也是朝生夕死的,将字符串常量池放到堆中,能够更高效及时地回收字符串内存
运行时数据区如图:

JDK1.8
由于永久代有固定的大小,且不容易调整,因此在一些场景下容易导致内存溢出。例如,如果应用程序中使用大量的动态生成类或者频繁地加载卸载类,就可能导致永久代溢出,从JDK 1.8开始永久代被移除,取而代之的是元空间(可以根据应用程序的需要动态调整其大小,避免了永久代的内存溢出,可以减少垃圾回收的压力)
运行时数据区如图:
