JAVA 对象头解析

一个Java对象在JVM中是由一个对应角色的oop对象来描述的,

比如instanceOopDesc用来描述普通实例对象,arrayOopDesc用来描述数组对象,而这些类型的oop对象均是继承自oopDesc

 

class oopDesc {
  friend class VMStructs;
  friend class JVMCIVMStructs;
 private:
  // 对象头  
  volatile markOop _mark;
  // 元数据
  union _metadata {
    // 对应的Klass对象  
    Klass*      _klass;
    narrowKlass _compressed_klass;
  } _metadata;

oopDesc主要包含两部分,一部分是_mark,一部分是_metadata

  • _mark _mark是一个markOop实例,它描述了一个对象的头信息,用于存储对象的运行时记录信息,如哈希值、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等:

 

 

 

源码位置:  hostspot/share/oops/markOop.hpp   (jdk10)

JAVA 对象头解析_第1张图片

  • _metadata 包含一个普通_klass和一个压缩后的_compressed_klass,详细信息参见OpenJDK Wiki。

 

markOop描述了对象的头部信息。

注意标记不是真正的oop而是一个单词。

由于历史原因,它被放置在oop层次结构中。

对象头的位格式:

  
32 bits:
  --------
             hash:25 ------------>| age:4    biased_lock:1 lock:2 (normal object)
             JavaThread*:23 epoch:2 age:4    biased_lock:1 lock:2 (biased object)
             size:32 ------------------------------------------>| (CMS free block)
             PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)

  64 bits:
  --------
  unused:25 hash:31 -->| unused:1   age:4    biased_lock:1 lock:2 (normal object)
  JavaThread*:54 epoch:2 unused:1   age:4    biased_lock:1 lock:2 (biased object)
  PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)
  size:64 ----------------------------------------------------->| (CMS free block)

  unused:25 hash:31 -->| cms_free:1 age:4    biased_lock:1 lock:2 (COOPs && normal object)
  JavaThread*:54 epoch:2 cms_free:1 age:4    biased_lock:1 lock:2 (COOPs && biased object)
  narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)
  unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)




 

问题:  Java对象如何存储?

对象的实例(instantOopDesc)保存在堆上,对象的元数据(instantKlass)保存在方法区(元空间?),对象的引用保存在栈上。

 

JAVA 对象头解析_第2张图片

hash: 保存对象的哈希码
age: 保存对象的分代年龄
biased_lock: 偏向锁标识位
lock: 锁状态标识位
JavaThread* 保存持有偏向锁的线程ID
epoch: 保存偏向时间戳

markOop中不同的锁标识位,代表着不同的锁状态:

JAVA 对象头解析_第3张图片

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(JVM源码,工具,API,速查)