36
votes

I want to know the location that JVM allocates to objects being placed in the system memory.

4
Ok, I'll ask: why?Oliver Charlesworth
@CiroSantilli烏坎事件2016六四事件法轮功 No. That one is asking whether something is a memory address. This one is asking how to get the memory address.user207421

4 Answers

40
votes

This is something you probably don't want to do.

If you really want to do this, something like this code might help:

package test;

import java.lang.reflect.Field;

import sun.misc.Unsafe;

public class Addresser
{
    private static Unsafe unsafe;

    static
    {
        try
        {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe)field.get(null);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static long addressOf(Object o)
    throws Exception
    {
        Object[] array = new Object[] {o};

        long baseOffset = unsafe.arrayBaseOffset(Object[].class);
        int addressSize = unsafe.addressSize();
        long objectAddress;
        switch (addressSize)
        {
            case 4:
                objectAddress = unsafe.getInt(array, baseOffset);
                break;
            case 8:
                objectAddress = unsafe.getLong(array, baseOffset);
                break;
            default:
                throw new Error("unsupported address size: " + addressSize);
        }       

        return(objectAddress);
    }


    public static void main(String... args)
    throws Exception
    {   
        Object mine = "Hi there".toCharArray();
        long address = addressOf(mine);
        System.out.println("Addess: " + address);

        //Verify address works - should see the characters in the array in the output
        printBytes(address, 27);

    }

    public static void printBytes(long objectAddress, int num)
    {
        for (long i = 0; i < num; i++)
        {
            int cur = unsafe.getByte(objectAddress + i);
            System.out.print((char)cur);
        }
        System.out.println();
    }
}

But

  • not portable across JVMs or even different versions
  • objects can move because of GC at any time, and cannot synchronize across GCs so results might not make sense
  • not tested across all architectures, endianess, etc. might make this not work everywhere
11
votes

Without using JVM-specific features this cannot be done. Java deliberately hides the location associated with each object to give the implementation more flexibility (the JVM often moves objects around in memory when doing garbage collection) and to improve security (you can't use raw pointers to trash memory or access nonexistent objects).

3
votes

You can use http://openjdk.java.net/projects/code-tools/jol to parse object layouts and get locations in memory. For one object you can use:

System.out.println(
    GraphLayout.parseInstance(someObject).toPrintable());
System.out.println("Current address: " + VM.current().addressOf(someObject));
-5
votes

I want to know the location that JVM allocates to objects

You can't, because it doesn't exist. It changes over time due to garbage-collector action. There is no such thing as 'the location'.