如何获取堆转储中使用的对象 ID

How to get Object ID as used in Heap Dump

我希望能够获得在 Java 堆转储(通过 jmap 或 JMX 等创建)中使用的相同 ID。这是为了能够识别静止 运行 应用程序中的活动对象与同一应用程序的旧内存快照(堆转储)。

我已经进行了一些测试,很明显不是 hashCode,也不是 JDI 唯一 ID(您可以在调试器中看到)。

通过检查 sun.jvm.hotspot.utilities 中的代码,我假设它是内存中的对象地址。但我对 sun.misc.Unsafe 的测试也没有导致与堆转储中使用的相同的 id 值。 (有关不安全的解释,请参阅此处:http://zeroturnaround.com/rebellabs/dangerous-code-how-to-be-unsafe-with-java-classes-objects-in-memory/

有什么想法吗?谢谢 :) !

创建堆转储有两种不同的方法:

  1. 从 JVM 进程内部使用 Dynamic Attach Mechanismjmap 这样做),或
  2. 来自外部进程使用 Serviceability Agent (jmap -F)

在这两种情况下,堆转储中的对象 ID 都是创建转储时对象的内存地址。这是相关的 HotSpot 源代码:[1] and [2].

但是,这个对象 ID 在转储文件之外没有意义,因为对象可以在垃圾收集期间在内存中移动。

另一个问题是很难(甚至不可能)从 Java 应用程序中获取 Java 对象的可靠地址 - 同样,因为对象可能会沿着堆移动并且因为对象引用的表示在不同的体系结构、环境和 JVM 选项之间可能会有所不同,例如取决于堆大小,UseCompressedOops 等。这里是 an example 从 Java 应用程序中获取对象地址,但这不能保证适用于所有 JVM 版本。