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

问题描述 投票:27回答:4

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

java object memory-management
4个回答
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等测试,可能会使这在任何地方都无法正常工作

11
投票

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


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

-4
投票

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

你不能,因为它不存在。由于垃圾收集器操作,它会随时间而变化。没有“位置”这样的东西。

© www.soinside.com 2019 - 2024. All rights reserved.