2016-09-24 13 views
0

参照変数は、オブジェクトへの参照を格納します。この参照を取得する唯一の方法は、アドレスではなくオブジェクトのハッシュコードを返すtoString()メソッドを呼び出すことです。オブジェクトの物理アドレスを取得する方法はありますか?Javaでオブジェクトの物理アドレスを取得できますか?

class Point { 
int x; 
int y; 
} 
public class MyClass { 
    public static void main(String[] args) { 
    Point p = new Point(); 
} 
} 

私の質問は「pオブジェクトの物理アドレスを取得できますか?」です。もちろん、私はp.toString()がそのハッシュコードを返すことを知っています。それで、私はその住所を入手する可能性について尋ねています。私はそれを使用するか、それを変更する必要はありません。私はそれを得ることが可能であることを知る必要があります。

私が質問している理由は、多くの異なる場所で同じ質問が多かったのですが、回答がありませんでした。私はそれが不可能であるという私の提案を確認する必要があります。しかし、この場合、新しい質問が発生します。JVMがオブジェクトを見つけ出す方法?

+0

具体的な問題を明確にしたり、詳細を追加して必要なものを正確に強調してください。現在書かれているとおり、あなたが求めていることを正確に伝えるのは難しいです。この質問を明確にする方法については、How to Askページを参照してください。 –

+3

オブジェクトの物理アドレスにアクセスすることはできず、JVMによって自由に変更できます。 toString()の "アドレス"は、アドレスと同じではなく、* IDハッシュ*です。 – Bohemian

+4

'sun.misc.Unsafe'を使ってオブジェクトの現在の物理アドレスを取得できます(http://stackoverflow.com/questions/38114099/understanding-how-to-memcpy-with-theunsafe/38189553#38189553)。しかし、ガベージコレクタはすぐに蹴り、オブジェクトを別のアドレスに移動させるかもしれません。したがって、取得したアドレスは、取得した瞬間から無効になる可能性があります。 –

答えて

0

。この参照を取得する唯一の方法は、アドレスではなくオブジェクトのハッシュコードを返すtoString()メソッドを呼び出すことです。

hashCodeはランダムに生成された番号であり、アドレスとは関係ありません。

オブジェクトの物理アドレスを取得する方法はありますか?

Unsafeを使用して取得することはできますが、興味のあるもの以外は実行しないでください。

JVMがオブジェクトを検出する方法は?

JVMは参照をインデックスとして使用します。このインデックスは、間接的であってもよく、すなわちオブジェクトがどこにあるかの配列であってもよく、例えば翻訳などであってもよい。 CompressedOopsは、インデックスに8を掛け、必要に応じてオフセットを追加することがあります。

Oracle/OpenJDKを使用してCompressedOopsを無効にすると、変換されていない64ビットアドレスを取得できます。これを行うには

簡単な方法は、配列 にオブジェクトのアドレスを入れて、その後、彼らはあなたの参照のサイズに応じてintまたはlongであるかのように配列の要素にアクセスすることです。

Object i = 0x12345678; 
System.out.printf("indentityHashCode = %08x%n", System.identityHashCode(i)); 
Object[] obj = {i}; 
assert Unsafe.ARRAY_OBJECT_INDEX_SCALE == 8; // 8 bytes per reference. 
long address = UNSAFE.getLong(obj, (long) Unsafe.ARRAY_OBJECT_BASE_OFFSET); 
System.out.printf("%x%n", address); 
for (int j = 0; j < 24; j++) 
    System.out.printf("%02x ", UNSAFE.getByte(address + j) & 0xFF); 
System.out.println(); 

// now some really scary sh!t 
UNSAFE.putLong(i, 8L, UNSAFE.getLong(0L, 8L)); 
System.out.printf("`i` is now a %s and is %x%n", i.getClass(), i); 

私はここに他の多くの例最も有用なトリックの

https://github.com/peter-lawrey/Performance-Examples/tree/master/src/main/java/vanilla/java/unsafe

一つを持っているが、GCの前と後に、オブジェクトが配置されているかを確認することができることです。自宅でこれを試してみてください。 NSFW。

関連する問題