This is the 8th day of my participation in the August Text Challenge.More challenges in August

JOL profile

JOL (Java Object Layout) is a mini-toolkit for analyzing object layout schemes in the JVM. These tools make extensive use of Unsafe, JVMTI, and serviceable proxy (SA) to decode actual object layouts, diagrams, and references.

Jol openjdk.java.net/projects/co official document…

This article focuses on using JOL to view the structure of an object. For more information on the structure of an object, see juejin.cn/post/699330…

Structure information about the object header

Use the JOL tool to view the Java object layout

Introduce joL dependencies

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.16</version>
</dependency>
Copy the code

Creating an object Example

Class Foo has an integer variable I, a long integer variable j, and a reference type variable bar

  1. Bar
public class Bar {
    private int k;
}
Copy the code
  1. Foo
public class Foo {
    private int i;
    private long j;
    private Bar bar;
}
Copy the code

Printing Object Information

Prints object information without HashCode
@Test
public void test(a) {
    Foo foo = new Foo();
    System.out.println(ClassLayout.parseInstance(foo).toPrintable());
}
Copy the code

Output result:

org.ywb.Foo object internals:
OFF  SZ          TYPE DESCRIPTION               VALUE
  0   8               (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   4               (object header: class)    0xf8011ce4
 12   4           int Foo.i16 8 0long Foo.j24 4 0org.ywb.Bar Foo.bar                   null28 (4object alignment gap)    
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
Copy the code
  1. The output object header contains two parts, 8 bytes for MarkWord and 4 bytes for ClassPoint, respectively. Since no synchronized code block uses the object as a lock, the object is in a lock-free state, i.e., the flag bit for the bias lock is 0, and the flag bit for the lock is 01.

  2. The object body now has three attributes: I of type int (4 bytes), j of type long (8 bytes), and a reference of type 4.

Number of bytes of Java data types

  1. Because the JVM specifies that the object header size must be an integer multiple of 8 bytes, which is not enough because 8 + 4 = 12, an additional 4-byte object alignment gap is required to fill the header.

  2. After the object is initialized, the

    method is automatically called to assign values to the object properties. By default, the int and long types are copied to 0, and the reference type is assigned to NULL

  3. The total size of the object is 32 bytes

Prints object structure information with hashCode

Once the object generates hashCode, the JVM records it in the Mark Word in the object header;

Note that only the unoverridden object.hashCode () method is called, or the System.identityHashCode (obj) method is recorded in the Mark Word; If a new hashcode() method is called, it will not be recorded in Mark Word.

Once the object has generated hashCode, it cannot enter the biased lock state; That is, as long as an object has computed hashCode, it cannot enter the biased lock state; When an object is currently in a biased lock state and its Hashcode needs to be computed, its biased lock is removed and the lock expands to a heavyweight lock.

@Test
public void test(a) {
    Foo foo = new Foo();
    int code = foo.hashCode();
    System.out.println(ClassLayout.parseInstance(foo).toPrintable());
}
Copy the code

Output result:

org.ywb.Foo object internals:
OFF  SZ          TYPE DESCRIPTION               VALUE
  0   8               (object header: mark)     0x000000694f943101 (hash: 0x694f9431; age: 0)
  8   4               (object header: class)    0xf8011d21
 12   4           int Foo.i16 8 0long Foo.j24 4 0org.ywb.Bar Foo.bar                   null28 (4object alignment gap)    
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
Copy the code

Not much different, except that the object HashCode is stored in the object header.

Array object structure information
@Test
public void test(a) {
    Foo[] foos = new Foo[4];
    System.out.println(ClassLayout.parseInstance(foos).toPrintable());
}
Copy the code

Output result:

[Lorg.ywb.Foo; object internals:
OFF  SZ          TYPE DESCRIPTION               VALUE
  0   8               (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   4               (object header: class)    0xf8011d234 (12array length4.alignment/padding gap16 16)org.ywb.Foo Foo; .<elements> N/A Instance size:32 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total
Copy the code
  1. Added an array length property to the header of the object. This property is not available in normal objects, only if the type is array.
  2. There is only one property in the object body, and since our array request is of length 4 and a reference is of size 4, the size of the property is 4 * 4 = 16