[In-depth understanding of multithreading] Java object header (3)

In the previous article, we started with the source code of HotSpot and introduced the object model of Java. This article introduces the object header of Java on the basis of the previous article. It mainly introduces the role, structure and relationship between the object header and the lock.

Java Object Model Review and Errata

In the last article, part of the description about the object header was wrong, I have corrected it in my blog article. Let me restate it here.

For each Java class, when it is loaded by the JVM, the JVM will create one for the class instanceKlassand save it in the method area to represent the Java class at the JVM layer. When we use new to create an object in Java code, the JVM will create an instanceOopDescobject that contains the object header and instance data.

What exactly is the object header mentioned here?

class oopDesc {
  friend class VMStructs;
 private:
  volatile markOop  _mark;
  union _metadata {
    wideKlassOop    _klass;
    narrowOop       _compressed_klass;
  } _metadata;
}

_markThe sum in the above code is _metadataactually the definition of the object header. It has been introduced _metadatabefore, so I won't repeat it here. Since this topic mainly wants to introduce the knowledge related to JAVA concurrency, this article will introduce it _mark , namely mark word.

The object header information is an additional storage cost independent of the data defined by the object itself. Considering the space efficiency of the virtual machine, Mark Word is designed as a non-fixed data structure to store as much information as possible in a very small space. Reuse your own storage space according to the state of the object.

The design of the markword is very similar to the network protocol header: the mark word is divided into multiple bit intervals, and the bits are given different meanings in different object states. The following figure describes the meaning of each bit interval of the mark word when the object is in different states on a 32-bit virtual machine.


Similarly, in the source code of HotSpot, we can find the definition of the object header object, which will confirm the description of the above figure one by one. Corresponds to the markOop.hpp class.

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
};

As can be seen from the above enumeration definition, the object header mainly contains information such as GC generation age, lock status flag, hash code, epoch and so on.

从上图中可以看出,对象的状态一共有五种,分别是无锁态、轻量级锁、重量级锁、GC标记和偏向锁。在32位的虚拟机中有两个Bits是用来存储锁的标记为的,但是我们都知道,两个bits最多只能表示四种状态:00、01、10、11,那么第五种状态如何表示呢 ,就要额外依赖1Bit的空间,使用0和1来区分。

在32位的HotSpot虚拟机 中对象未被锁定的状态下,Mark Word的32个Bits空间中的25Bits用于存储对象哈希码(HashCode),4Bits用于存储对象分代年龄,2Bits用于存储锁标志位,1Bit固定为0,表示非偏向锁。

markOop.hpp类中有关于对象状态的定义:

  enum { locked_value             = 0,
         unlocked_value           = 1,
         monitor_value            = 2,
         marked_value             = 3,
         biased_lock_pattern      = 5
  };

简单翻译一下:

locked_value(00) = 0

unlocked_value(01) = 1

monitor_value(10) = 2

marked_value(11) = 3

biasedlockpattern(101) = 5

关于为什么要定义这么多状态,上面提到的轻量级锁、重量级锁、偏向锁以及他们之前的关系,会在下一篇文章中重点阐述,敬请期待。





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325439675&siteId=291194637