深刻Java對象的地址的應用剖析。本站提示廣大學習愛好者:(深刻Java對象的地址的應用剖析)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻Java對象的地址的應用剖析正文
在傳統的Java編程中,你將不再須要從內存中處置Java對象或地位。 當你在服裝論壇t.vhao.net上評論辯論這一點,提出的第一個成績是為何你須要曉得Java對象的地址? 它是一種有用的成績。 但以往,我們保存停止實驗的權力。摸索未知范疇的成績並沒有甚麼錯。我想出了一個應用sun公司包的試驗。Unsafe是一個屬於sun.misc包。對你來講能夠這個包有點生疏,看看源代碼和辦法,你便可以曉得我所指的是甚麼了。
Java的平安治理供給了足夠的隱蔽來確保你其實不能那末輕易的玩弄內存。作為第一步,我想到了要獲得一個Java對象的內存地位。直到摸索,我也已經是100%的信念,這是弗成能找到的地位 Java中對象的地址。
Sun的Unsafe.java API文檔顯示我們無機會取得地址應用辦法objectFieldOffset。這個辦法似乎在說:“申報中的類存儲分派它的地位在一個特定范疇。“ 它還說,“這只是個中一個拜訪器的cookie傳遞給不平安堆內存“。 不管若何,我可以或許從它的類的存儲分派存儲一個對象的內存地位。你可以辯論說,我們所獲得的是否是一個對象的相對物理內存地址。然則,我們拿到了邏輯內存地址。上面的法式將遭到你的風趣!
作為第一步,我得拿到Unsafe類的一個對象。這是很艱苦的,由於結構函數是公有的。 有一個名為getUnsafe一個辦法,該辦法前往不平安的對象。Java平安治理請求您給源代碼特權。我用到了一點反射然後獲得了一個實例。我曉得有更好的辦法來取得實例,但我選擇了以下的辦法來繞開平安治理。
應用Unsafe的對象,只須要挪用objectFieldOffset和staticFieldOffset。成果就是類的內存分派地址。
以下的實例法式可以運轉在JDK1.6上。
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class ObjectLocation {
private static int apple = 10;
private int orange = 10;
public static void main(String[] args) throws Exception {
Unsafe unsafe = getUnsafeInstance();
Field appleField = ObjectLocation.class.getDeclaredField("apple");
System.out.println("Location of Apple: "
+ unsafe.staticFieldOffset(appleField));
Field orangeField = ObjectLocation.class.getDeclaredField("orange");
System.out.println("Location of Orange: "
+ unsafe.objectFieldOffset(orangeField));
}
private static Unsafe getUnsafeInstance() throws SecurityException,
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
}
}
API引見:
boolean compareAndSwapInt(Object obj,long fieldoffset, int expect, int update);
修正 obj對象的(fieldoffset)Int 屬性值,若屬性值為expect,則修正為 update ,前往true,若屬性值不為expect則不修正,前往false
boolean compareAndSwapObject(Object obj,long Fieldoffset, Object expect, Object update);
修正 obj對象的(fieldoffset)屬性值,若屬性值為expect,則修正為 update ,前往true,若屬性值不為expect則不修正,前往false
long objectFieldOffset (Field field);
獲得 filed在對象中的偏移
void park(boolean flag, long time);
使以後線程期待
void unpark(Thread thread)
使以後線程停滯期待
Object getObject(Object obj,long fieldoffset);
獲得 obj 的 偏移為fieldoffset 的屬性
int getInt(Object obj,long fieldoffset);
獲得 obj 的 偏移為fieldoffset 的int屬性