5

假设我有这个变量:

...
Somekindofobject var = new Somekindofobject();
...

我想知道 var 在堆上的位置(按地址,如 0x08 等),并将地址打印出来。

是否可以?

4

5 回答 5

8

我正在开发一个作为输入 java 程序的程序,以及打印出有关变量访问的文件信息的仪器代码。我可以确定同一类对象的两个字段之间的唯一方法是通过他们在堆上的地址。因此,我需要堆上的地址

您可以使用System.identityHashCode来获得相同性的概念。它并不完美,但它非常好。如果您确实获得了对象的堆地址,请记住允许 JVM 移动对象(并且在分代垃圾收集器将长期存在的对象提升到老一代时经常这样做),因此对象的堆位置不是在所有情况下都可以很好地代表身份。

于 2011-01-10T20:24:28.397 回答
3

你可以试试这篇 javaPaper 的文章:Java 对象的地址

它是关于使用包中的Unsafesun.misc来获取地址。

于 2011-01-10T20:18:32.173 回答
1

即使您设法获得了对象的堆地址,也不能保证在您使用它时该对象仍然存在。垃圾收集器可以随时将对象移动到另一个位置。与 .NET 不同,java 不支持内存固定。如果您希望将数据从本机代码推送到地址中,则可能需要 DirectByteBuffer。

于 2011-01-10T20:26:31.047 回答
1

除了提到 Unsafe 这很好......很有用(我自己在生产环境中使用过它)。还有另一种解决方案不会将 Java 地址作为本机指针返回,它被称为直接 java.nio.ByteBuffer,它的设计正是考虑到了这个想法。它通过直接 ByteBuffer 分配的内存不在 Java 堆中分配,也不是标准垃圾收集的对象。然后,当然,ByteBuffer 通过 ByteBuffer.address() 提供直接指针

于 2011-01-10T20:44:59.867 回答
0

鉴于您的目标,我认为唯一的解决方案是JVMTI。您将使用 {SetTag} 操作将唯一标识符与每个对象相关联。然后监听 {FieldModification} 事件。

于 2011-01-10T21:11:21.180 回答