我想知道JVM分配給放置在系統內存中的對象的位置。如何獲取java中的對象的內存位置?
回答
這是你可能不想做的事情。
如果你真的要做到這一點,像這樣的代碼可能會有所幫助:
package test;
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class Addresser
{
private static Unsafe unsafe;
static
{
try
{
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe)field.get(null);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static long addressOf(Object o)
throws Exception
{
Object[] array = new Object[] {o};
long baseOffset = unsafe.arrayBaseOffset(Object[].class);
int addressSize = unsafe.addressSize();
long objectAddress;
switch (addressSize)
{
case 4:
objectAddress = unsafe.getInt(array, baseOffset);
break;
case 8:
objectAddress = unsafe.getLong(array, baseOffset);
break;
default:
throw new Error("unsupported address size: " + addressSize);
}
return(objectAddress);
}
public static void main(String... args)
throws Exception
{
Object mine = "Hi there".toCharArray();
long address = addressOf(mine);
System.out.println("Addess: " + address);
//Verify address works - should see the characters in the array in the output
printBytes(address, 27);
}
public static void printBytes(long objectAddress, int num)
{
for (long i = 0; i < num; i++)
{
int cur = unsafe.getByte(objectAddress + i);
System.out.print((char)cur);
}
System.out.println();
}
}
但
- 不能跨越的JVM甚至不同版本
- 對象可以因爲移動便攜的GC,無法在GC之間同步,因此結果可能不合理
- 未測試交流羅斯所有的架構,字節順序等可能使這個不行到處
即使UseCompressedOpps處於打開狀態,64位Sun JDK上的'unsafe.addressSize()'似乎也會返回8。使用'unsafe.arrayIndexScale(Object []。class)',在這種情況下返回4,似乎更有可能使用這種技術(畢竟,您將對象存儲在Object數組中)。 對於壓縮的oops,返回的地址不是真正的地址 - 它可能會右移3位,等等。 – BeeOnRope
如果不使用特定於JVM的功能,則無法執行此操作。 Java有意隱藏與每個對象相關聯的位置,從而爲實現提供更大的靈活性(JVM通常在執行垃圾回收時在內存中移動對象)並提高安全性(不能使用原始指針來垃圾內存或訪問不存在的對象)。
那麼Object.hashCode()的默認實現呢?它返回對象的內存地址,不是嗎?它使用@prunge告訴的不安全類嗎?我知道這是一個本地方法,所以也許這只是C++中的一個指針到int的轉換? –
'Object.hashCode()'不會*返回對象的內存地址。它是特定於實現的。我花了好幾個月的時間研究一個JVM的JavaScript實現,在這裏你不能使用原始地址,只需要爲每個對象增加一個計數器來實現Object.hashCode()。在一些實現中,這可能是'Object.hashCode()'的工作原理,但是由於許多JVM在內存中移動對象,所以你不能依賴這一點。 – templatetypedef
'System.identityHashcode(Object)'比返回對象的內存地址複雜得多,即使這看起來是這樣。首先,即使GC移動了對象,它也必須返回相同的值。這通常需要*保存*對象中的值。 (有些JVM以一種聰明的方式來做到這一點,從而最大限度地減少開銷......但最終還是會付錢的。) –
您可以使用http://openjdk.java.net/projects/code-tools/jol解析對象佈局。對於一個對象,你可以使用:
System.out.println(
GraphLayout.parseInstance(someObject).toPrintable());
a)僅鏈接答案在這裏不被認爲是很好的答案,請參閱[答案]。 b)這個問題已經有其他幾個高質量的答案;這添加了什麼? – EJoshuaS
感謝您的反饋。它增加了對標準現代工具JOL的參考,這些不在這裏。更清潔和便攜的方式,這爲作者的任務取一行代碼,而不是不安全的例子。我還爲這個問題添加了代碼示例。 – egorlitvinenko
- 1. 內存中的Java RMI對象位置
- 2. Java獲取對象屬性的位置
- 3. 獲取對象的內存
- 4. 如何獲取對象內的對象?
- 5. 如何獲取組中對象的畫布相對位置?
- 6. 從c#對象中獲取的內存
- 7. jsAnim:獲取對象位置
- 8. 如何刪除在Python中引用對象的內存位置?
- 9. 如何通過內存堆中的java對象獲取佔用的空間?
- 10. 在Android上的內存中如何佈置Java對象?
- 11. C++如何指定內存中的位置以獲取數據?
- 12. 如何獲取場景中每個對象的當前位置?
- 13. 如何在Java中獲取Sheet對象的位置/索引Apache POI
- 14. C#獲取對象的位置遞歸
- 15. ParseQueryAdapter獲取對象的位置
- 16. 如何在另一個對象的座標系中獲取對象位置THREE.js
- 17. 如何在UIView對象中獲取對象的位置和大小c
- 18. 獲取Java中的JSON對象內JSON對象
- 19. 如何設置和獲取存儲在Redis中的對象?
- 20. 如何獲取散列內的鍵/值對的位置?
- 21. 如何從java中的WebElement對象獲取對象
- 22. 在Android中將位圖對象緩存到內存的位置何處停止?
- 23. 獲取最新的內部或在哪裏位置對象
- 24. 如何在Java中獲取對象類?
- 25. 如何在保存Mongoose中的對象後獲取對象ID?
- 26. 如何獲取與放置事件的位置相對應的範圍對象?
- 27. 如何從特定的內存位置獲取結構?
- 28. 如何獲取對象的世界位置(Three.js)
- 29. 如何根據遊戲對象的位置獲取角度?
- 30. 如何從android工作室的對象線獲取位置
好吧,我會問:爲什麼? –
[Java中變量的內存地址]的可能重複(http://stackoverflow.com/questions/1961146/memory-address-of-variables-in-java) –