OOP 是 jvm 中用于抽象及映射 java 对象实例的 C++ 基础结构, 这对于普通 java 程序员来说颇为陌生, 但如果想搞懂 jvm 的底层原理, 我们就必须仔细学习这个 C++ 类的实现细节;

OOP 全称是 Ordinary Object Pointer (普通对象指针):

  • 它是 jvm 内部对 java 对象的直接表示;
  • 它是 garbage collector 直接操作的对象结构;

OOP 的继承结构

1
2
3
4
5
oop (顶级基类)
├── instanceOopDesc // 普通 java 对象实例
├── arrayOopDesc // 数组基类
│ ├── objArrayOopDesc // 对象数组
│ └── typeArrayOopDesc // 基本类型数组

OOP 的数据结构

一个普通 java 对象 (instanceOopDesc) 在内存中的布局:

1
2
3
4
5
6
7
8
9
+--------------------+
| 对象头 (markOop) | // Mark Word
+--------------------+
| Klass 指针 | ---> InstanceKlass (方法表、字段信息等) // 指向类的元信息
+--------------------+
| 实例数据 | // 对象字段值
+--------------------+
| 4K 对齐填充 | // 可选
+--------------------+

OOP 与 Klass 的关系:

  • Klass存储类元数据 (所有实例共享);
  • OOP存储实例数据 (每个对象独有);

 

  1. 对象创建时:

    • 当 new 一个对象时, jvm 分配 instanceOopDesc;
    • instanceOopDesc 中的 Klass 指针指向对应的 InstanceKlass 地址;
  2. 方法调用时:

    • 通过对象的 Klass 指针找到类元数据;
    • 通过Klass中的 vtable/itable 找到正确的方法地址;

 
为什么需要这种设计?

  1. 节省内存:

    • 避免每个对象都携带完整的类信息;
    • 通过指针共享类元数据;
  2. GC 优化:

    • 对象头 (markOop) 与元数据分离;
    • GC 可以专注于对象实例数据;

Mark Word

实例数据