Java物件與JVM(三) Java物件在Java虛擬機器中的引用訪問方式
Java物件與JVM(三)
Java物件在Java虛擬機器中的引用訪問方式
在前面兩篇文章中瞭解到Java物件例項是如何在HotSpot虛擬機器的Java堆中建立的,以及建立後的記憶體佈局是怎樣的。
下面我們詳細瞭解在Java堆中的Java物件是如何訪問定位的:先來了解reference型別資料是什麼,再來了解兩種訪問方式:使用控制代碼或者使用直接指標(HotSpot虛擬機器使用了直接指標的方式訪問物件)。
1、reference型別
java程式通過reference型別資料操作堆上的具體物件;
(A)、JVM層面的引用
reference型別是引用型別(Reference Types)的一種;
JVM規範規定reference型別來表示對某個物件的引用,可以想象成類似於一個指向物件的指標;
物件的操作、傳遞和檢查都通過引用它的reference型別的資料進行操作;
(B)、Java語言層面的引用
(i)、JDK1.2前的引用定義
如果reference型別的資料中儲存的數值代表的是另外一塊記憶體的起始地址,就稱這塊記憶體代表著一個引用;
這種定義太過狹隘,無法描述更多資訊;
(ii)、JDK1.2後,對引用概念進行了擴充,將引用分為:
(1)、強引用(Strong Reference)
程式程式碼普遍存在的,類似"Object obj=new Object()";
只要強引用還存在,GC永遠不會回收被引用的物件;
(2)、軟引用(Soft Reference)
用來描述還有用但並非必需的物件;
直到記憶體空間不夠時(丟擲OutOfMemoryError之前),才會被垃圾回收;
最常用於實現對記憶體敏感的快取;
SoftReference類實現;
(3)、弱引用(Weak Reference)
用來描述非必需物件;
只能生存到下一次垃圾回收之前,無論記憶體是否足夠;
WeakReference類實現;
(4)、虛引用(Phantom Reference)
也稱為幽靈引用或幻影引用;
完全不會對其生存時間構成影響;
唯一目的就是能在這個物件被回收時收到一個系統通知;
PhantomRenference類實現;
更多請參考JDK相關API說明;
對於軟引用,可以使用命令列選項"-XX:SoftRefLRUPolicyMSPerMB = <N>"來控制清除速率;
2、物件訪問方式
雖然定義的reference型別資料來作為物件記憶體資料的引用,但JVM規範沒有定義這個引用應該通過何種方式定位、訪問堆上的物件,也沒有不強制規定物件的內部結構應當如何表示;
這些都取決於JVM的實現,目前主流的物件訪問方式有兩種:
(A)、使用控制代碼
Java堆劃分一塊記憶體作為控制代碼池,reference中儲存就是物件的控制代碼地址;
物件控制代碼包含兩個地址:
(1)、在堆中分配的物件例項資料的地址;
(2)、這個物件型別資料地址;
如圖所示:
優點:物件移動時(垃圾回收時常見的動作),reference不需要修改,只改變控制代碼中例項資料指標;
(B)、使用直接指標
reference中儲存就是在堆中分配的物件例項資料的地址;
而物件例項資料中需要有這個物件型別資料的相關資訊(前面文章討論了HotSpot使用物件頭來儲存物件型別資料地址);
如圖所示:
優點:物件訪問時節省了一次指標定位的時間開銷,速度更快;
由於物件訪問非常頻繁進行,所以能較好提升效能;
HotSpot虛擬機器使用了直接指標的方式訪問物件;
到這裡,我們大體瞭解Java物件在HotSpot虛擬機器中的訪問定位方式, 判斷物件是否存在引用是垃圾收集的首要問題,只有沒有引用的物件才能被回收;後面我們將分別去了解:方法的呼叫與執行、JIT編譯、以及JVM垃圾收集相關內容……
【參考資料】
1、《深入理解Java虛擬機器:JVM高階特性與最佳實踐》第二版 第2章