JVM OopMap

OopMap

以下内容适用于 Hotsport JVM

什么是 Oop

官方解释:An object pointer. Specifically, a pointer into the GC-managed heap. (The term is traditional. One ‘o’ may stand for ‘ordinary’.) Implemented as a native machine address, not a handle. Oops may be directly manipulated by compiled or interpreted Java code, because the GC knows about the liveness and location of oops within such code. (See GC map.) Oops can also be directly manipulated by short spans of C/C++ code, but must be kept by such code within handles across every safepoint.

Ordinary object pointer,普通对象指针,指向 GC 管理的堆,即本机地址。

Java 对象的表示模型叫做“Oop-Klass”模型,包括两部分:

  1. Oop,用来描述对象实例信息
  2. Klass,用来描述 Java 类,包含了元数据和方法信息等

一个 Java 对象就包括两部分:数据和方法,分别对应到 Oop 和 Klass。JVM 运行时加载一个 Class 时,会在 JVM 内部创建一个 instanceKlass 对象,表示这个类的运行时元数据。创建一个这个 Class 的 Java 对象时,会在 JVM 内部相应的创建一个 instanceOop 来表示这个 Java 对象。instanceKlass 对象放在了方法区,instanceOop 放在了堆,instanceOop 的引用在 JVM 栈。

什么是 OopMap

OopMap 用于枚举 GC Roots。JVM GC 判断对象是否可以回收使用可达性分析的方法,可达性分析首先需要找到 GC Roots 对象

如果每次 GC 的时候都要遍历所有的引用,工作量是非常大的。并且在要保证期间不发生引用关系的变化,所有执行线程要停顿等待(STW),所以要想办法尽量减少这部分工作,缩短 STW 时间。

Java 中的 GC Root 有一种就是虚拟机栈(栈帧中的局部变量表)中引用的对象。GC 时,收集线程会对栈进行扫描,如果某个位置存的是引用类型,那么引用的对象暂时不能被回收(GC Root)。如果不是引用类型,收集线程并不关心。OopMap 就是一个映射表,记录了栈上的局部变量表中哪些位置是引用类型,在 GC 的时候只需要读取 OopMap 上的信息,是一种空间换时间的思想。

OopMap 使用

每个线程对应着一个栈,每个栈由多个栈帧组成,每个栈帧对应一个方法,一个方法里面可能有多个安全点(Safepoint),每个安全点对应一个 OopMap。

GC 发生时,线程运行到最近的一个安全点停下来,然后更新的 OopMap 。收集线程遍历每个栈帧的 OopMap,通过记录的被引用对象的内存地址,找到这些 GC Roots。

OopMap 避免了全栈扫描,加快找到 GC Roots 的速度。但是它的更根本的作用是,可以帮助 HotSpot 实现准确式 GC 。


Tags:

Add a Comment

电子邮件地址不会被公开。 必填项已用*标注