2015-06-03 25 views
1

我希望能夠獲得Java堆轉儲(通過jmap或JMX等創建的)中使用的相同ID。這是爲了能夠識別仍在運行的應用程序中的活動對象,而不是相同應用程序的舊內存快照(堆轉儲)。如何獲得在堆轉儲中使用的對象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/

任何想法?謝謝 :) !

+0

對象(或其任何超級對象)是否重寫hashCode?如果是這樣,你可能會運氣['System.identityHashCode()'](http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#identityHashCode%28java.lang。 Object%29) – blazetopher

+0

或者它可能像需要hashCode的十六進制值一樣簡單? 'Integer.toHexString(obj.hashCode())'... – blazetopher

+0

感謝您的評論,但沒有,正如我所說的不幸的是不是hashCode。也不是System.identiyHashCode(如果它沒有被覆蓋,它與普通對象hashCode相同)。不,十六進制或十進制無關緊要。最後它是相同的價值,對吧?大多數堆轉儲分析器傾向於將值顯示爲十六進制。在我的情況下,這個值是一個簡單的長整型值(可能是因爲64位jvm)。 –

回答

2

有兩種不同的方法來創建堆轉儲:從JVM進程內

  1. 使用Dynamic Attach Mechanismjmap這樣做),或從外部過程
  2. 使用Serviceability Agentjmap -F

在這兩種情況下,堆轉儲中的對象標識都是創建轉儲時對象的內存地址。以下是相關的HotSpot源代碼:[1][2]

但是,此對象標識在轉儲文件外部沒有意義,因爲在垃圾收集期間對象可以在內存中移動。

另一個問題是從Java應用程序中獲取Java對象的可靠地址是困難的(甚至是不可能的) - 同樣,因爲對象可能沿着堆移動,並且因爲對象引用的表示可能會有所不同不同的體系結構,環境和JVM選項,例如取決於堆的大小,UseCompressedOops等。這裏是an example從Java應用程序中獲取對象地址,但這不能保證適用於所有JVM版本。

相關問題