当一个Java类在被JVM加载后,JVM会给这个类创建一个instanceKlass,保存在方法区,用于在JVM层表示该Java类。
当我们在代码中new一个对象时,JVM会创建一个instanceOopDesc对象,包含了对象头以及实例数据。
对象头包括:
class oopDesc { friend class VMStructs; private: volatile markOop _mark; union _metadata { wideKlassOop _klass; narrowOop _compressed_klass; } _metadata; }
其中的_mark就是 mark word。
mark word划分为多个比特位区间,并在不同的对象状态下赋予比特位不同的含义。
以下描述了在32位虚拟机上在对象不同状态时mark word各个比特位区间的含义。
对象头对象的定义:
enum { age_bits = 4, lock_bits = 2, biased_lock_bits = 1, max_hash_bits = BitsPerWord - age_bits - lock_bits - biased_lock_bits, hash_bits = max_hash_bits > 31 ? 31 : max_hash_bits, cms_bits = LP64_ONLY(1) NOT_LP64(0), epoch_bits = 2 };
包括GC分代年龄、锁状态标记、哈希码、epoch等信息。
可以看出,对象状态一共有五种:无锁、轻量级锁、重量级锁、GC标记和偏向锁。
locked_value(00) = 0 unlocked_value(01) = 1 monitor_value(10) = 2 marked_value(11) = 3 biased_lock_pattern(101) = 5