Sun unsafe API

It is quite interesting that though Unsafe API is forbidden to be used in the “normal” java applications, it is still possible to access it, though it is strictly discouraged in the production code. I do it “just for fun” and don’t recommend for use in any “real” applications.

In short: unsafe API (sun.misc.Unsafe) allows access to native sun-specific API such as allocating chunk of native memory, get internal offsets for quick property sets and etc.
Though addressing Unsafe.getUnsafe generates compiler error it is possible to access it via reflection by reading static private properties from some classes, such as AtomicReference:

try {
    final Field unsafeField = AtomicReference.class.getDeclaredField("unsafe");
    unsafeField.setAccessible(true);
    final Unsafe u = (Unsafe) unsafeField.get(null);
    System.out.println("unsafe: " + u);
    // ...
catch (Exception e) { /* ... */ }

I was especially curious on quick, non-reflection driven property access.
It may be done via Unsafe.put* methods, such as Unsafe.putInt.

For example, if you have the following point object:

class Point2DV {
    int x;
    int y;
}

you may access x and y fields by addressing them directly.

The following snippet demonstrates it:

final long xOffset = u.objectFieldOffset(Point2DV.class.getDeclaredField("x"));
final long yOffset = u.objectFieldOffset(Point2DV.class.getDeclaredField("y"));
final Point2DV p = new Point2DV();
u.putInt(p, xOffset, 872);
u.putInt(p, yOffset, 1134);
System.out.println("offsetof(Point2DV.x) = " + xOffset + ", p.x = " + p.x);
System.out.println("offsetof(Point2DV.y) = " + yOffset + ", p.y = " + p.y);

It is quite curious to see that the offset of the very first property is 12 which tells us that *every* java object contains at least 12 bytes in memory which in its turn results that in reality even an object with no fields would occupy at least 16 bytes since jvm uses 8-bytes offsets).

Have fun (and never use it in real projects)!

Leave a Reply

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