Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.

Dangerous Code: How to be Unsafe with Java Classes & Objects in Memory

3. How can we get the memory address of an Object?

Getting the memory address of an object is trickier than getting the address of the class. In order to get the address, we use length and java.lang.Object typed helper array, whose length is 1.

Here are the steps for getting the address of an object:

  1. Set the target object as the first element (only element) of a helper array. Since the element is a complex type (non-primitive), its address is stored in an array with an index of 0.
  2. Then get the base offset of the helper array. The base offset of an array is the offset of starting point of elements to starting address of array object.
  3. We need to check the JVM address size:
    • If the JVM is 32 bit, read an integer value from <address_of_array> + <base_offset_of_array> via sun.misc.Unsafe class. This 4-byte integer value is the address of the target object.
    • If the JVM is 64 bit, read a long value from <address_of_array> + <base_offset_of_array> via sun.misc.Unsafe class. This 8-byte long value is the address of the target object.
For 32 bit JVM
	Object helperArray[] 	= new Object[1];
	helperArray[0] 		= targetObject;
	long baseOffset 		= unsafe.arrayBaseOffset(Object[].class);
	int addressOfObject	= unsafe.getInt(helperArray, baseOffset);

For 64 bit JVM
	Object helperArray[] 	= new Object[1];
	helperArray[0] 		= targetObject;
	long baseOffset 		= unsafe.arrayBaseOffset(Object[].class);
	long addressOfObject	= unsafe.getLong(helperArray, baseOffset);

You can think of targetObject as an instance of SampleClass, which was given in the above section. But also keep in mind that the object could be any instance of any class!


Class Memory Layout

32-bit JVM

	[header                ] 4  byte
	[klass pointer         ] 4  byte (pointer)
	[C++ vtbl ptr          ] 4  byte (pointer)
	[layout_helper         ] 4  byte
	[super check offset    ] 4  byte 
	[name                  ] 4  byte (pointer)
	[secondary super cache ] 4  byte (pointer)
	[secondary supers      ] 4  byte (pointer)
	[primary supers        ] 32 byte (8 length array of pointer)
	[java mirror           ] 4  byte (pointer)
	[super                 ] 4  byte (pointer)
	[first subklass        ] 4  byte (pointer)
	[next sibling          ] 4  byte (pointer)
	[modifier flags        ] 4  byte
	[access flags          ] 4  byte

64-bit JVM

	[header                ] 8  byte
	[klass pointer         ] 8  byte (4 byte for compressed-oops)
	[C++ vtbl ptr          ] 8  byte (4 byte for compressed-oops)
	[layout_helper         ] 4  byte
	[super check offset    ] 4  byte 
	[name                  ] 8  byte (4 byte for compressed-oops)
	[secondary super cache ] 8  byte (4 byte for compressed-oops)
	[secondary supers      ] 8  byte (4 byte for compressed-oops)
	[primary supers        ] 64 byte (32 byte for compressed-oops)
                                         {8 length array of pointer}
	[java mirror           ] 8  byte (4 byte for compressed-oops)
	[super                 ] 8  byte (4 byte for compressed-oops)
	[first subklass        ] 8  byte (4 byte for compressed-oops)
	[next sibling          ] 8  byte (4 byte for compressed-oops)
	[modifier flags        ] 4  byte
	[access flags          ] 4  byte

For a reference point to the above sections, check out: http://hg.openjdk.java.net/jdk7/hotspot/hotspot/file/9b0ca45cd756/src/share/vm/oops/klass.hpp

The memory layout of the SampleClass can be detailed as below for 32-bit JVM. 128 bytes are listed from its starting address.

java class memory layout samplebaseclass

java class memory layout samplebaseclass

And the memory layout of the SampleBaseClass can be detailed as below for 32-bit JVM. Also 128 bytes are listed from its starting address.

java class memory layout samplebaseclass

We will only explain the important fields. The colored numbers also match the legend mapping given below.

header always has the constant value of “0x00000001”.

klass pointer is the pointer (0x38970v8a8 for both of classes) to definition of java.lang.Class class in memory, since this memory structure refers to a class.

C++ vtbl ptr is the pointer to the virtual table definition structure of a defined class. A virtual table is a mechanism used to support dynamic dispatch, which is the process of selecting which implementation of a polymorphic method to call at runtime.

layout helper refers to the shallow size of the instance. This size is calculated by considering the field layout alignment mechanism of the JVM. In our environment, object alignment size is 8 bytes.

super is the pointer to cthe lass definition of a super class, which is SampleBaseClass in our example. In this example, the value of this field is 0x34104b70 , which is address of the class definition of SampleBaseClass as you can see. For the SampleBaseClass class, this field value is 0x38970000 which is the address of java.lang.Object class. Because in Java, every class is a subclass of the Object class ☺.

modifier flags refer to the Java class modifiers which could be “public”, “protected”, “private”, “abstract”, “abstract”, “static”, “final” and “strictfp”. The “modifier flags” value of class is calculated by operating “Bitwise OR” operation on modifier values of target class. In our example, SampleClass class is “public” and “final” class. Hence “modifier flags” value for this class is calculated as “0x00000001 | 0x00000010 = 0x00000011 ”. SampleBaseClass is only “public” class and so its “modifier flags” value is “ 0x00000001 ”. The values for the modifiers are listed below.

Public

0x00000001

Protected

0x00000002

Private

0x00000004

Abstract

0x00000400

Static

0x00000008

Final

0x00000010

Strict

0x00000800