How To Write Directly to a Memory Locations In Java
chip_ao_01.jpg

If anyone has ever told you, you cannot write directly to memory locations in java, then they are wrong. Well, to be precise, they are half-wrong, you can write to memory locations as long as the memory is control by the JVM.

Although this is possible, I strongly recommend that you don’t do it. Failing to get your code 100% correct will cause the JVM to crash. There maybe cases where you wish to optimize your code and write to memory directly but I would only do this as a last resort.

On the Hotspot JVM, you are able to write and read directly to memory. One of the advantages of this technique is that is very fast, however it comes with no safe guards usually provided by the Java APIs. Its also not documented by SUN.

Use the java class sun.misc.Unsafe, some of the methods you may be interested in are :

public native long getByte(long address);
public native void putByte(long address, byte value);
public native long getLong(long address);
public native void putLong(long address, long value);
public native long allocateMemory(long size);
public native long reallocateMemory(long l, long l1);
public native void setMemory(long l, long l1, byte b);
public native void copyMemory(long l, long l1, long l2);

You can't instantiate the class directly as it has a private constructor, so you will have to create an instance like this :

Unsafe unsafe = null;
 
try {
   Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
   field.setAccessible(true);
   unsafe = (sun.misc.Unsafe) field.get(null);
} catch (Exception e) {
   throw new AssertionError(e);
}

you can then call

import java.lang.reflect.Field;
 
import sun.misc.Unsafe;
 
public class Direct {
 
    public static void main(String... args) {
        Unsafe unsafe = null;
 
        try {
            Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (sun.misc.Unsafe) field.get(null);
        } catch (Exception e) {
            throw new AssertionError(e);
        }
 
        long value = 12345;
        byte size = 8; // a long is 64 bits (http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html)
        long allocateMemory = unsafe.allocateMemory(size);
        unsafe.putLong(allocateMemory, value);
        long readValue = unsafe.getLong(allocateMemory);
        System.out.println("read value : " + readValue);
 
    }
}

this will output :

read value : 12345
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License