preface

Week N of working from home.

Do not know the company is still in….

Back to the main body, object head.

Object headers can be a starting point for learning Java.

Given that there is a door to delving into the Java language, object headers are such an entry point that there is no technical point, but one that needs to be known.

“Where are the synchronized markers?” , “object how old ah object generation age where to see” and so on, just learn Java is unavoidable these questions, these are closely related to the object head.

If the “object header” is not clear to the reader, you can continue to read, this article will show you the “object” 🧠 roughly what is installed.


The body of the

Introduction to the

First throw out the basic concept, behind the author has a specific practice.

The Object header is a literal translation, which is a bit stiff. In my opinion, it can be called “Object name card”, which mainly contains the basic information of the Object, such as:

  • layout
  • The GC state
  • type
  • sync
  • (identity) hash code
  • Array length (You have to be an array)

Identity hash code meansWithout rewritingPass hashcode computed by the JVM.

The entire object header consists of two parts: klass Pointer and Mark Word.

Of course, before introducing these two things, it is important to note that this article is described in a 64-bit environment based on JDK1.8 by default, which is a standard configuration.

klass pointer

Klass Pointer is usually 32 bits (4 bytes), 64 bits if you have a good reason to turn off the default pointer compression (-xx: -usecompressedoops).

However, there is one more detail: according to the calculation, after the heap size exceeds 32GB, no error will be reported even if pointer compression is not turned on, but pointer compression will fail.

But this author is to have no actual test, the reason is….

The heap size should be 32GB+ memory, and some memory should be reserved for non-heap and OS, which is not available on my machine. However, I found other people’s test articles at the bottom of this article, interested friends can read.

The contents of a Klass Pointer are a pointer to information about its class metadata that the JVM uses to determine which instance of a class this object is.

What do you mean? If you have a reference to a Person instance, that’s where you’ll find the metadata, as shown here:


Mark Word

Mark Word is an important point of knowledge for Java programmers.


The “scene” in the table, you can also understand as “state”, an object is in a state at a point in time, but the states may switch.

That is, the object you are using is in the “row” state of the current table.

On a 64-bit virtual machine, Mark Word takes up 8 bytes of 64-bit space.

The specific contents include:

  • Unused: unused
  • Hashcode: The hashcode mentioned above refers to the identity Hash code used in this article
  • Thread: Identifies the thread biased to the lock record
  • Epoch: Timestamp to verify the validity of biased locks
  • Age: generational age
  • Biased_lock Bias lock flag
  • The lock lock symbol
  • Pointer_to_lock_record Lightweight lock LOCK RECORD pointer
  • Pointer_to_heavyweight_monitor Indicates the monitor pointer

Cms_free: cms_free: cms_free: cms_free: cms_free: cms_free: cms_free: cms_free: cms_free: cms_free

Cms_free has a relationship with the CMS collector, because the CMS algorithm is a mark-clean collector, so the memory fragmentation problem is to maintain unreachable objects in a list free list, the author inferred that here should be marked objects in the free list.

The conclusion about CMS_free is speculated by the author, so you don’t have to believe it. If you think what the author said is incorrect, please tell me.

If you think I’m wrong, but you can’t prove it, don’t take it seriously. After all, JDK14 CMS has been removed.

Beginners can start by looking at the line below the unlocked state.

If you read this and think back to my previous statement that “Mark Word is an important piece of knowledge for Java programmers,” you know why. This part has a lot to do with the program, such as:

Why promoted to older age Settings (XX:MaxTenuringThreshold) cannot exceed15 ?

Because age is given four bits of space, the maximum is 1111(binary) or 15, there is no more space to store.

Why is yoursynchronizedLock objects without the “legendary” bias lock optimization?

Because HashCode is not computed after the object is instantiated, it is computed by the call and put in mark Word.

You’ve called the hashCode method (or implicitly called it: stored in a Hashset, the map’s key, called the default unoverridden toString() method, etc.) and the “pit” is occupied, so there’s no room to store the thread ID that the bias lock was intended to store, so it’s a lightweight lock.

(or you simply forgot to add – XX: when testing BiasedLockingStartupDelay = 0)

It seems that the design is a little unreasonable and reasonable, and the design at the bottom is so plain and boring.

This article will focus on “object headers”, so it will not focus on locks.

Such as:synchronizedA hashcode calculation method called within a block, even if it has a biased lock, is revoked and inflated to a heavyweight lock. If you do, you may see a separate article about locking in the future.

practice

Jol is a tool provided by openJDK to analyze object size, layout and other information.

This article uses the simplest maven introduction project approach for testing. You can also choose from the command line, both of which are described in the jol link above.

With joL introduced, let’s try printing object layouts.

Array object layout

    public static void main(String[] args) {

// Declare an array of length 3306

int[] intArr = new int[3306];

// Use jol's ClassLayout tool to analyze the object layout

System.out.println(ClassLayout.parseInstance(intArr).toPrintable());

}



print:

------------------------------------------------------

[I object internals:

OFFSET SIZE TYPE DESCRIPTION VALUE

0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)

4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)

8 4 (object header) 6d 01 00 f8 (01101101 00000001 00000000 11111000) (-134217363)

12 4 (object header) ea 0c 00 00 (11101010 00001100 00000000 00000000) (3306)

16 13224 int [I.<elements> N/A

Instance size: 13240 bytes

Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

Copy the code

If you are looking at jol’s printed layout for the first time, you can look directly at the following image I have highlighted:

The three parts of the object header confirm the klass Pointer and Mark Word mentioned above, respectively, as well as the array’s unique length attribute.

The value of “each line” is displayed in three bases on the right, echoing the above:

The original Hashcode methods (including the System.identityHashcode method) have not been called, so the hashcode position is 0.

As you can see from the figure, the object is very “clean” when it is first instantiated. At first glance, there are two rows of zeros, but only one is jarring.

In fact, it is 001, which is the biased lock mark + lock mark mentioned above. The status of all locks is as follows:

Deviation lock mark Lock symbol state
0 01 unlocked
1 01 Biased locking
00 Lightweight lock
10 Heavyweight lock
11 The GC tag

Now it’s clear that even though we have a 1, we’re actually in an unlocked state.

Going back to the layout, since it is an array object, the length of the array is saved in line 4, not for non-array objects.

The object size calculation is also very accurate, i.e. 13224(an int is four bytes times 3306) + 16 = 13240 bytes.

Tips for your own practice

Seeing how unpretentious the object layout is, you can try it out.

Here are a few tips:

  • The effects of HashCode on bias locking and weight locking mentioned above
  • Above mentioned-XX:BiasedLockingStartupDelayEffects of parameters on bias lock testing
  • Note the influence of the size end of the test machine on the order of results. Generally, everyone’s machine is small end, so the printing order of value is opposite to the field order described in the picture at the beginning of Markword above.

If you don’t pay attention to these points, you may end up with a blank face, not knowing which bits correspond to which fields, or even the result is not what you expected.

The last

There are a lot of details about the structure of objects that you can read more about. This article only briefly introduces the “Object Header” part.

After reading this article, have you and the author the same, want to say:

The design on the ground floor is so unpretentious and boring.

Just kidding, in fact look more, you will find very fun 😊.

Develop recommendations

  • Heapdump-is-a-lie is an article about the size of objects presented by heapdump and the accuracy of the JoL tool.

  • MarkOop. HPP JDk8 about markWord source section

  • MarkWord. HPP JDk14 about the markWord source section, observe a CMS after what has changed

  • Objectheader.txt Layout of object headers in three cases (64-bit, 64-bit compressed pointer, 32-bit)

  • Hotspotglossary.html hotspot’s glossary, this article covers only a few words in the object header.

  • My friends on machines with 35 gigabytes of memory tested virtual machines with 32 gigabytes of Heap memory and found that there was actually Less to store. This is the problem of pointer compression mentioned in this article.