2012-03-09 57 views
6

我目前正在爲Java 1.7構建本機JVMTI代理。問題是我需要索引關於特定Java對象實例的一些數據。所以我的問題是我可以使用jobject類型的值作爲對象的實例ID來檢索我的索引數據?如何唯一區分Java的對象實例

我已查找有關jobject類型的語義是什麼的任何信息。它是Object的內存位置上的指針嗎?它是一個堆棧指針地址?它是否是JVM內部結構的地址?所以我無法弄清楚jobject的價值是否獨一無二,並且隨着Java對象的生活而不可變。

感謝您的幫助。

編輯

按照JNI的規範發現here,jobject似乎是對對象實例的指針。

+0

到目前爲止,你做了什麼?根據你所獲得的信息,你試圖獲取和索引或檢索的信息的確切類型是什麼? – 2012-03-09 19:35:04

+0

可能類似:http://stackoverflow.com/questions/909843/java-how-to-get-the-unique-id-of-an-object-which-overrides-hashcode – 2012-03-10 00:31:15

+0

其實,我的問題是關於一個用C語言編寫的JVMTI代理程序。我想將Object的實例用作緩存目的的主鍵(例如實現爲哈希映射或紅黑樹)。現在,我使用SetTag標記每個對象的唯一標識&GetTag功能。 – Gu0sur20 2012-03-10 21:12:46

回答

2

當你說你「jobject類型的價值」我猜你的意思是由toString返回的值。如果你看一下Java文檔它指出:

Object類的toString方法返回一個包含其中的對象是一個實例,則在符號字符'之類的名稱的字符串@」,以及該對象的哈希碼的無符號十六進制表示。換句話說,該方法返回一個字符串等於值:

getClass().getName() + '@' + Integer.toHexString(hashCode()) 

如果你看一下Java文檔的hashCode方法它指出:

每當調用上一個Java應用程序的執行期間,在同一對象一次以上,hashCode方法必須一致地返回相同的整數

並且還

儘管合理實際,類Object定義的hashCode方法確實爲不同的對象返回不同的整數。 (這一般是通過將該對象的內部地址轉換成一個整數來實現的,但不是由的JavaTM編程語言不需要這種實現技巧。)

更新:迴應萊恩的評論:System.identityHashCode會把你原來的哈希碼,即使哈希碼方法被覆蓋。然而,像評論一樣,它並不是真正獨特的。

所以我想你的問題的答案是肯定它是不可變的,它很可能是獨一無二的,但你應該閱讀你的JVM的文檔或源代碼。

+0

HashCode對每個對象都是唯一的。但是,如果您覆蓋equals,則它應該被覆蓋,以便它與任何其他等同於equals的對象相同。 – 2012-03-10 00:29:57

+3

@Ryan不,它肯定是**不總是獨一無二的。很明顯這樣:你將很難保證在64位系統上使用32位的唯一標識符。 – Voo 2012-03-10 00:35:25

+0

此外,equals/hashcode約定表示2個相等的對象具有相同的散列碼。所以如果兩個對象在語義上相同,它們的哈希碼應該是相同的。儘管兩個不相等的對象可能具有相同的哈希碼,所以System.identityHashCode(或任何哈希碼實現)不能保證唯一性。 – 2012-03-10 00:42:26

1

至少在HotSpot中,jobject確實是一個指向對象位置的指針,也就是說,取消引用它會爲每個對象提供一個唯一的地址,這是您請求的「唯一且不可變的身份」的一半關於。問題在於垃圾收集過程中地址可能會更改,因爲HotSpot可以移動對象。

JVMTI GetTag和SetTag函數內部使用哈希表從對象位置到標記。無論何時移動對象,HotSpot都會更新此散列表,這是您無法從JVMTI代理的位置輕鬆複製的。如您所說已經在做的事情,爲您的標籤分配您自己的唯一標識值可能是唯一的途徑。