【问题标题】:is it possible to get address on heap of a variable in java?是否可以在java中的变量堆上获取地址?
【发布时间】:2011-06-06 18:19:15
【问题描述】:

可以说我有这个变量:

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

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

有可能吗?

【问题讨论】:

  • 如果您只想打印对象,那么知道它在堆上的位置有什么好处?你真正想要完成什么?
  • @Anon:我想他的意思是把地址打印出来。
  • 我正在开发一个程序,该程序将 java 程序作为输入,并测试代码打印出有关变量访问的文件信息。我可以确定同一类对象的两个字段之间的唯一方法是通过他们在堆上的地址。因此,我需要堆上的地址
  • 通常使用 Java 字节码来检测 Java 字节码。在这种情况下,您不需要“地址”。也许这里潜伏着另一个/更好的问题?如果需要“地址”,那么我所知道的唯一方法是带有固定功能的 JNI,但恐怕这可能不会“如你所料”那样工作。
  • 看起来您需要使用调试框架,这些通常会提供某种唯一的对象 ID。

标签: java pointers memory-management heap-memory memory-address


【解决方案1】:

我正在开发一个程序 输入java程序和工具 打印到文件的代码 有关变量访问的信息。这 我可以确定的唯一方法 相同对象的两个字段 类是由他们在堆上的地址。 因此,我需要堆上的地址

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

【讨论】:

  • 这可能会在 32 位系统上很好地解决 OP 的问题。
  • System.identityHashCode 现在是基于每个线程种子的随机生成器
  • 你能详细说明一下吗? System.idenetityHashCode(var) 给了我什么?我需要能够让我确定同一类的不同对象的同一字段之间的东西。
  • 网站崩溃并丢失了之前的答案,但为了轻松跟踪对象身份(而不是相等),我猜 IdentityHashMap 就是你要找的。 System.identityHashCode 即使在 32 位环境中也不稳定,虽然不太可能发生冲突。对象序列化 (java.io.ObjectOutputStream) 跟踪具有类似(与 identityHashMap)结构的引用。
  • 一般来说,如果您只有“对象”,则不应使用 HashMap 之类的,因为它们需要正确的 hashCode 和 equals 实现,故意错误地编写 equals (+hashcode) 可以跟踪现有的相当多的数据结构。但是,所有这些都超出了问题的范围。
【解决方案2】:

你可以试试javaPaper的这篇文章:Address of a Java object

就是使用sun.misc包中的Unsafe类来获取地址。

【讨论】:

  • 绝对可怕。注意 Unsafe (选择名称是有原因的)和 sun.misc (“私有”实现特定的包)。另请注意,这是针对逻辑地址而不是物理地址。为一篇有趣的文章 +1。
  • 这将为您提供对象内字段的地址,而不是对象本身。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 这不是我需要的,因为我对我得到的输入代码一无所知。但我喜欢这个主意,所以 +1;
    【解决方案5】:

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

    【讨论】:

      猜你喜欢
      • 2012-03-27
      • 2017-08-21
      • 2011-07-19
      • 1970-01-01
      • 2020-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多