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

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

living dangerously

Let’s get laid out…the class and object structure of Java in memory

Have you ever wondered about the internals of Java memory management? Do you ask yourself weird questions like:

  • How much space does a class take up in memory?
  • How much space do my objects consume in machine memory?
  • What’s the deal with the alignment of object properties in memory?

If these questions sound familiar, then you are in the right place. For Java geeks like us over here at RebelLabs, these mysterious questions have been orbiting our minds for a long time: if you are interested knowing more about the instrumentation of classes, knowing how classes are laid out will make it easier to get some specific fields from memory, or hack these fields within memory on the fly. This means that you can actually change the data or even the code within the memory!

Other points that might be striking your interest are “Off-Heap Memory” and “High Performance Serialization” implementations, which are a couple of good samples based on the object memory structure. This covers the ways to access memory addresses of classes and their instances, the layouts of these classes and instances in memory, along with a detailed explanation on the layouts of the object fields. We’re hoping to explain the content as simply as possible, but even so this article isn’t for Java beginners and knowledge of some Java programming principles are needed.

N.B. The writing below on the layouts of classes and objects are specific to Java SE 7, so it’s not recommended to automatically assume that any of it will be applicable in past or future versions of Java. For your convenience, we’ve placed the sample code for this article in a GitHub project for convenience, which you can find here:

What is the way of Direct Memory Access in Java?

Java was initially designed as a safe, managed environment. Nevertheless, Java HotSpot VM contains a “backdoor” that provides a number of low-level operations to manipulate memory and threads directly. This backdoor class – sun.misc.Unsafe – is widely used by JDK itself in packages like java.nio or java.util.concurrent. However, using this backdoor is certainly not suggested for use in the production environment, because this API is extremely dangerous, non-portable, and volatile. The Unsafe class provides an easy way to look into HotSpot JVM internals and to do some tricks. Sometimes it can be used to study VM internals without C++ code debugging, sometimes it can be leveraged for profiling and development tools.

How to be Unsafe
The sun.misc.Unsafe class was so unsafe that JDK developers added special checks to restrict access to it. Its constructor is private and the caller of the factory method getUnsafe() should be loaded by Bootloader. As you can see at line 8 in the snippet below, this goodie is not even loaded by any class loader, so its class loader is null. It will throw a SecurityException to prevent intruders.

public final class Unsafe {
   private Unsafe() {}
   private static final Unsafe theUnsafe = new Unsafe();
   public static Unsafe getUnsafe() {
      Class cc = sun.reflect.Reflection.getCallerClass(2);
      if (cc.getClassLoader() != null)
          throw new SecurityException("Unsafe");
      return theUnsafe;

Fortunately there is theUnsafe field that can be used to retrieve the Unsafe instance. We can easily write a helper method to do this via reflection, as seen below. (

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

Some useful features of Unsafe

  1. VM “intrinsification” i.e. CAS (compare-and-swap) used in Lock-Free Hash Tables. For example the compareAndSwapInt method makes real JNI calls into native code that contains special instructions for CAS. You can read more about CAS here:

  2. The sun.misc.Unsafe functionality of the host VM can be used to allocate uninitialized objects (by “allocateInstance” method) and then interpret the constructor invocation as any other method call.

  3. You can track the data from the native address. It’s possible to retrieve an object’s memory address using the java.lang.Unsafe class, and operate on its fields directly via unsafe get/put methods!

  4. With the allocateMemory method, memory can be allocated from off-heap. For example, the DirectByteBuffer constructor internally calls it when the allocateDirect method is invoked.

  5. The methods, arrayBaseOffset and arrayIndexScale, can be used to develop arraylets, a technique for efficiently breaking up large arrays into smaller objects to limit the real-time cost of scan, update or move operations on large objects.

In the next section, as we get the memory address of a class, we give some examples of using “Unsafe”.

  • Rafael Winterhalter

    Brilliant article / summary. Thanks. So far, I was always checking property offsets via the Unsafe in order to find a maximum and added some padding but this was of course rather a worst case estimate. By the way, I found it easier to reflectively call the Unsafe constructor instead of reading the singleton field. Some JVMs have a different name for the field while offering the same API for Unsafe. Looking forward to the next series article.

  • Serkan Özal

    Thanks for your comments Rafael. The next article will be about Java OffHeap implementations and may be an alternative way to existing solutions. If you are interested in Java Memory Model and Unsafe. you can look at my project Jillegal on GitHub (, Especially’ you may be interested in with this class (

  • Eddie Oscar

    Very insightful article, thanks! This answered some tough questions for me on unsafe/offheap access.. I also played around with your Jillegal implementation trying to map a Java pointer (a DirectByteBuffer.address()) to access from external process (C++ implementation) but JVMUtil.toNativeAddress() does not seem to convert it to the correct address for some reason despite -XX:-UseCompressedOops. Any idea why the addressing mismatch between Java off-heap and another process?

  • z0ltan

    Wow, a lot of the text seems to have been copied directly from here – Shameful.

  • Oleg Šelajev

    thanks for bringing it to our attention. We’re trying to contact the authors and figure out what has happened and how to fix the situation.

  • Serkan Özal

    Hi Eddie,

    Thanks for your interest.

    Jillegal uses Hotspot SA internally for getting compressed-reference shift size and base address from JVM itself via exported reading symbols in dynamic library (jvm.dll,, …). So there shouldn’t be any problem about address convertion.

    Why do you think there is an addressing mismatch between Java off-heap and another process? Can you a little bit explain.

  • Haasip Satang

    Nice article. I’m having one question in relation to heap dumps though: I always thought that the “object id” in the heap dump files is taken from the actual address of the object or class. So I played around with it now and tried to identify the addresses of some objects and classes using the way you outlined here and then compare it with the values from my heap dump. Result –> they are not the same.

    Why do I think the heap dump uses the object addreeses as id? That’s my understanding from playing with the classes in the sun.jvm.hotspot.utilities package (like HeapHprofBinWriter, etc).

    Any idea what is the difference between the two (the id in a heap dump and the address obtained via Unsafe)?