classpointer是jvm在对象创建时直接写入对象头的原生指针,指向元空间中该类的klass结构体起始地址;64位默认8字节,开启压缩后为4字节,用于快速类型识别与方法分发。

对象头里的 ClassPointer(也叫 Klass Pointer)不是“计算出来”的,而是由 JVM 在对象创建时直接写入的固定地址值,它指向方法区(JDK 8+ 是元空间)中该类对应的 类元数据结构(Klass 结构体) 的起始位置。
ClassPointer 的本质是内存地址
它是一个原生指针(Native Pointer),在 64 位 JVM 中默认占 8 字节;若开启指针压缩(-XX:+UseCompressedClassPointers),则压缩为 4 字节,指向元空间中经过对齐的 Klass 地址。这个值不是字符串名或符号引用,而是实实在在的、可被 CPU 直接解引用的虚拟内存地址。
指向目标:方法区中的 Klass 而非 Class 对象
注意区分两个易混淆概念:
-
Class 对象:是 Java 层可见的
java.lang.Class实例,存放在堆内存中,是类加载过程的产物; -
Klass 结构体:是 JVM 内部 C++ 实现的类元数据描述结构(如
InstanceKlass),存放在方法区/元空间,包含 vtable、itable、字段偏移、方法入口等运行时关键信息。
ClassPointer 指向的是后者——即 Klass,它是 JVM 快速识别对象类型、分发虚方法、校验字段访问权限的基础。
指向过程发生在对象分配阶段
当执行 new User() 时,JVM 做三件事:
- 在堆中划分内存(如 TLAB),初始化对象头;
- 从当前线程关联的类元数据缓存中,取出
User.class对应的InstanceKlass*地址; - 将该地址直接写入新对象的对象头中 Klass Pointer 字段。
整个过程不查表、不解析、不反射,是纯指针赋值,毫秒级完成。
为什么能“精准”?靠类加载与内存管理协同保证
Klass 在元空间中的地址一旦分配,在类卸载前就固定不变;而元空间本身由操作系统 mmap 分配大块连续内存,JVM 维护其内部空闲链表和地址映射。因此只要类未被卸载,ClassPointer 就始终有效且准确——它不是“查找结果”,而是“预置锚点”。











