如何在java中获取对象的内存位置?

时间:2011-08-14 22:40:18

标签: java object memory-management

我想知道JVM分配给放置在系统内存中的对象的位置。

4 个答案:

答案 0 :(得分:32)

这可能是你不想做的事情。

如果确实想要这样做,那么像这样的代码可能会有所帮助:

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();
    }
}

但是

  • 无法跨JVM或甚至不同版本移植
  • 对象可以随时因GC而移动,并且无法在GC之间同步,因此结果可能没有意义
  • 未在所有体系结构,endianess等进行测试可能会使这无处不在

答案 1 :(得分:11)

如果不使用特定于JVM的功能,则无法完成此操作。 Java故意隐藏与每个对象关联的位置,以使实现具有更大的灵活性(JVM通常在执行垃圾收集时在内存中移动对象)并提高安全性(您不能使用原始指针来废弃内存或访问不存在的对象)。

答案 2 :(得分:-2)

您可以使用http://openjdk.java.net/projects/code-tools/jol来解析对象布局并获取内存中的位置。对于一个对象,您可以使用:

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

答案 3 :(得分:-4)

  

我想知道JVM分配给对象的位置

你不能,因为它不存在。由于垃圾收集器操作,它会随时间而变化。没有' 位置'。