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

时间:2015-06-03 19:32:02

标签: java heap-dump objectid jvmti

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

我已经测试了一点,它显然不是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 个答案:

答案 0 :(得分:3)

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

  1. 来自JVM进程内部使用Dynamic Attach Mechanismjmap这样做)或
  2. 使用Serviceability Agentjmap -F)从外部流程
  3. 在这两种情况下,堆转储中的对象ID是创建转储时对象的内存地址。以下是相关的HotSpot源代码:[1][2]

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

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