1. 程式人生 > >Java物件與JVM(三) Java物件在Java虛擬機器中的引用訪問方式

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章