方法区与永久代、元空间之间的关系
方法区是JVM规范中定义的一块内存区域,用来存储类元数据、方法字节码、即时编译器需要的信息等
永久代是Hotspot虚拟机对JVM规范的实现(1.8之前)
元空间是Hotspot虚拟机对JVM规范的实现(1.8以后),使用本地内存作为这些信息的存储空间
因此其实永久代以及元空间其实就是对JVM方法区的一种具体实现
上面左侧的箭头按照创建的时间顺序,Heap表示堆,Metaspace表示元空间。
我们想要加载类,首先需要一个类加载器Class Loader。
之后当我们要加载类的时候,例如上面加载的X类,那么此时他就是将X类的元信息加载到了我们的元空间中,然后他也会在堆中创建X.class对象。而X类的原始信息此时就在元空间中了,如果想要访问元信息,那么就需要通过一个Java类去访问,也就是这里的X.class对象。Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口。
同理类Y也是。
因此在进行类加载的时候,就会把类的原始信息放入到元空间中。
而对于元空间中内存的释放,是没有那么容易的。
他要求我们的类加载器被回收的时候,元空间的类的原始信息才会被回收。
也就是在堆中类X和类Y的对象被回收完毕之后,此时如果没有需要加载其他类了,那么此时类加载器就会被回收,之后元空间的类原始信息也会被回收。
也就是不光光是对象实例不被使用,对象对应的Class类不再被使用了,以及类加载器不再被使用了才能释放元空间中的原始数据。