JVM OOP Map的理解

757 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

仅代表个人理解,如有错误欢迎指正

OOPMap(ordinary object pointer map)

OOPMap是什么,为什么会出现?

在收集器枚举根节点的过程中,需要在一个保持一致性的快照中进行,否则对象的引用关系不断变化会导致结果的准确性缺失,所以在进行枚举时,所有的用户线程必须停顿 可达性分析算法中从GC Roots中寻找引用链来判断对象是否存活 那GC Roots就需要时间去枚举,若收集器一个不漏的去查找栈的执行上下文和全局引用位置,就会过于耗时,所以虚拟机是能直接获取到哪些地方存放着对象引用的 这个地方就是OOP Map

什么时候生成OOPMap?

  • 栈里和寄存器内的引用 在即时编译中,在安全点下栈里和寄存器里哪些位置是引用

  • 对象内的引用 类加载动作完成时,HotSpot 就会计算出对象内什么偏移量上是什么类型的数据(字段是基本数据类型还是引用数据类型)

注:把存储单元的实际地址与其所在段的段地址之间的距离称为段内偏移,也称为有效地址或偏移量,因此,实际地址=所在段的起始地址+偏移量

OOPMap图解

JVM中,一个线程拥有一个栈,一个栈有许多栈帧,一个栈帧就是一个方法调用,一个方法可能有多个OOP Map 例如,假设两个方法都只有一个OOP Map:

// 方法1存储在栈帧3
public void testMethod1() {
    // 栈里和寄存器内的引用
    DemoD demoD = new DemoD();
}

// 方法2存储在栈帧8
public void testMethod2() {
    // 栈里和寄存器内的引用
    DemoA demoA = new DemoA();
    // 对象内的引用
    demoA.setDemoC(new DemoC());
    
    // 栈里和寄存器内的引用
    DemoA demoB = new DemoB();
} 

image-1655285673314