元空间存储五类数据:一、Java类的结构化元数据;二、运行时常量池;三、静态变量的定义及部分值;四、JIT编译相关元信息;五、类加载器自身元数据及其管理结构。
如果您正在排查JVM内存使用异常或类加载相关问题,需明确元空间(Metaspace)中实际承载的数据内容,则必须厘清其存储边界与构成要素。以下是元空间具体存储的数据类型清单:
一、Java类的结构化元数据
该部分保存每个已加载类在运行时必需的静态描述信息,直接支撑字节码验证、链接与反射操作。这些数据与类加载器强绑定,生命周期与其一致。
1、类的全限定名、访问修饰符(如public、final、interface等)。
2、直接父类与实现的接口的符号引用。
3、字段(Field)信息:包括名称、描述符(Descriptor)、访问标志、常量值(若为编译期常量)。
4、方法(Method)信息:包括名称、描述符、访问标志、字节码指令数组(code属性)、异常表、注解等。
5、内部类、封闭类、外围类的关联关系信息。
二、运行时常量池(Runtime Constant Pool)
这是每个类或接口专属的常量池运行时表示,由类加载阶段从class文件的constant_pool结构解析而来,独立于堆内存,驻留于元空间内。
1、编译

2、符号引用的解析结果缓存:包括类、字段、方法、接口方法的符号引用及其解析后的直接引用(在首次解析后可能被替换)。
3、动态计算的常量:如invokedynamic指令关联的BootstrapMethods属性所生成的调用点信息。
三、静态变量(Static Fields)
类的静态变量本身不存于元空间,但其**引用位置与初始值定义**属于类元数据的一部分;而静态变量的**实际值存储位置**取决于其类型:基本类型和String字面量直接内联在元数据中,引用类型则指向堆中对象。
1、static final基本类型常量(如public static final int MAX = 100)的值直接嵌入元数据结构。
2、static final String常量若为编译期常量,则其内容存于运行时常量池中。
3、非final或非编译期常量的static字段,其字段定义(名称、类型、修饰符)存于元数据,而运行时值存放于堆中对应类的Class对象的静态变量槽(static field slot)。
四、JIT编译后的本地代码(Code Cache 关联部分)
严格来说,JIT编译生成的机器码主要存放于独立的Code Cache区域,但元空间与之存在紧密协同:元空间中保存与这些编译代码强关联的元信息,确保可安全卸载。
1、方法的可执行入口地址映射(即nmethod元数据)。
2、反优化(deoptimization)所需的信息结构,如栈映射表(stack map table)、调试信息、去优化桩(uncommon trap stub)的元数据。
3、与特定类加载器绑定的编译单元归属标识,用于类卸载时同步回收对应编译代码。
五、类加载器相关元数据
元空间并非仅存储“类”,而是以类加载器为单位组织内存块,因此加载器自身的关键状态也纳入管理范围。
1、类加载器对象(ClassLoader instance)在元空间中的类型描述(即其自身的Class元数据)。
2、该加载器所加载的所有类元数据的索引与链表结构。
3、加载器的委托父链关系快照(用于双亲委派机制的运行时校验)。
4、当且仅当类加载器对象被垃圾回收时,其在元空间中占用的所有元数据才被整体释放。








