PoiNtEr->: Memory Locations In Java

                             Difference between a dream and an aim. A dream requires soundless sleep, whereas an aim requires sleepless efforts.

Search This Blog

Thursday, February 16, 2012

Memory Locations In Java


In Java, Memory is controlled by JVM .So its almost impossible to write on a particular memory location without crashing it.While you might be thinking why am i interested in address location as it has no use in java.I Would say i bother about addresses because i belong to C system programming ,so Memory address matters always for me .So to get it i experimented a little bit ,tried to find it on google.So finally here it goes,In java their is a stupid class named "Unsafe" which can help us to find address of java.Yeah stupid because it has very less sources available on internet.
         Now you might be thinking why its name is Unsafe because it handles the most unsafe methods to be used thats why...


Java’s security manager provides sufficient cover and ensures you don’t fiddle with memory that easily. As a first step, I thought of getting the memory location of a java object. Until the exploration, I too was 100% confident that it was not possible to find the location address of an object in java.

Sun’s Unsafe.java api documentation shows us an opportunity to get the address using the method objectFieldOffset. That method says, “Report the location of a given field in the storage allocation of its class“. It also says, “it is just a cookie which is passed to the unsafe heap memory accessors“. Whatsoever, I am able to get the storage memory location of an object from the storage allocation of its class.



import sun.misc.Unsafe;

import java.lang.reflect.Field;

public class ObjectLocation {

 private static int apple = 10;
 private int orange = 10;

 public static void main(String[] args) throws Exception {
  Unsafe unsafe = getUnsafeInstance();

  Field appleField = ObjectLocation.class.getDeclaredField("apple");
  System.out.println("Location of Apple: "
    + unsafe.staticFieldOffset(appleField));

  Field orangeField = ObjectLocation.class.getDeclaredField("orange");
  System.out.println("Location of Orange: "
    + unsafe.objectFieldOffset(orangeField));
 }

 private static Unsafe getUnsafeInstance() throws SecurityException,
   NoSuchFieldException, IllegalArgumentException,
   IllegalAccessException {
  Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
  theUnsafeInstance.setAccessible(true);
  return (Unsafe) theUnsafeInstance.get(Unsafe.class);
 }
}


Output:
Location of Apple: 336
Location of Orange: 8


On the 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 getAddress(long address);
public native void putAddress(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 = 1;
        long allocateMemory = unsafe.allocateMemory(size);
        unsafe.putAddress(allocateMemory, value);
        long readValue = unsafe.getAddress(allocateMemory);
        System.out.println("read value : " + readValue);
    }
}



Output :

read value : 12345


No comments:

Post a Comment