最近在看OpenJdk的源码,对对象头部分有了一个更直观的理解。同时,对象头中的MarkWord部分,又包含了对不同锁状态的标识,故以此为起点,梳理下不同锁状态的表示及不同锁状态的转换。
1、对象头
JVM内部,使用 OOP-Klass 二分模型来表示类和对象,OOP用来表示Java对象实例,Klass用来表示Java类。在Java应用程序运行过程中,每创建一个Java对象,在JVM内部就会相应地创建一个OOP对象来对应(具体为instanceOopDesc对象)。而每加载一个Java类,也会对应创建一个Klass对象来对应(具体为instanceKlass对象)。
Java对象在内存中的布局,可分为连续的两部分:instanceOopDesc + 实例数据。数组对象为:arrayOopDesc + 实例数据。
这里的 instanceOopDesc 与 arrayOopDesc,即为对象头。对象头中的Mark Word,即 OopDesc 基类中的 _mark 成员,存储对象运行时信息,如Hash Code、Age、锁状态标识、线程持有的锁、偏向线程ID、偏向时间戳等。对象头中的元数据指针,即 OopDesc 基类中的 _metadata 成员,指向描述对象所对应 Java 类的 Klass 对象。
2、锁状态<