Playing with Unsafe – Finding Object Address

sun.misc.Unsafe class is loaded with lot of features specific to Oracle VM. It's a sort of backdoor entry into the world of JVM which otherwise is not accessible through normal Java API's.

CAUTION: These tricks are implementation specific and I have only tested this on Mac OSX.

Getting Reference to Unsafe

There are lot of blogs around the which explains this, but here is the code for simplicity.

public static Unsafe getUnsafe() {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe)f.get(null);
} catch (Exception e) { /* ... */ }
return null;
}

Getting Address Size

You can know the size(32/64 bit) of VM using the following function.

unsafe.addressSize()

If the output is 4, its a 32 bit JVM. For a 64 bit JVM it would return 8.

Getting the Address of the Object

Have tried a lot but couldn't find a direct way to get the location of an Object. There are indirect ways using which you can get the address of the Object via Array.

Solution 1: Using an Array

To get the address of an object, create an array and add the object to the array. The code looks something like this.

public long getObjectAddess(Object o) {
Object[] objects = {o};
long baseOffset = unsafe.arrayBaseOffset(Object[].class);
return unsafe.getLong(objects, baseOffset);
}

Solution 2: Using another Object

This solution involves using the object whose address needs to be known, as field of another container object. We create a simple Pointer object. The code looks something like this.

class Pointer {
Object pointer;
}

public long getObjectAddressUsingNestedObject(Object o) {
Pointer pointer = new Pointer();
pointer.pointer = o;
try {
long offset = unsafe.objectFieldOffset(Pointer.class.getDeclaredField("pointer"));
return unsafe.getLong(pointer, offset);
} catch (NoSuchFieldException e) {
return -1;
}
}

These two solutions should return the same value, if used on the same object.

The numbers are negative, so need to normalize them using the following

(~0L >>> 32) &  address;

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.