對象如何訪問
之前的文章中袱蚓,介紹過Java虛擬機棧的知識版述。
在Java虛擬機棧中,每個線程執(zhí)行一個方法時姻锁,都會創(chuàng)建一個棧幀枕赵,棧幀用于存儲這個方法的一些信息,其中包括局部變量表位隶,也就是該方法中用到了哪些局部變量拷窜。
局部變量表存儲了編譯期可知的基本數(shù)據類型(boolean int double等)、引用數(shù)據類型(創(chuàng)建的對象)和returnAddress類型(指向一條指令涧黄,方法執(zhí)行完后要做什么)篮昧。每個局部變量都會占用1個局部變量空間(double和long類型會占用2個局部變量空間),簡稱為Slot弓熏。
其中恋谭,引用數(shù)據類型就跟我們今天要說的對象的訪問定位有關。
在我們程序方法中挽鞠,我們通過new的方式來創(chuàng)建一個對象疚颊。創(chuàng)建的對象保存在Java堆中狈孔,而創(chuàng)建的變量保存在Java棧里。那么材义,當我們程序實際使用到該對象時均抽,該如何去訪問堆中的對象呢?
Java程序通過棧上的reference(局部變量)數(shù)據來操作堆中具體的對象其掂,reference(局部變量)數(shù)據中保存這堆中對象的引用油挥,但是Java虛擬機規(guī)范中并沒有告知該引用以何種方式去定位、去訪問堆中對象的具體位置款熬。
目前深寥,主流的訪問方式有:使用句柄和直接指針。
使用句柄
使用句柄來訪問的話贤牛,Java堆中會劃分出一塊內存用作句柄池惋鹅,reference中存儲的就是對象的句柄地址,而句柄中實際上包含了對象的實例數(shù)據與類型數(shù)據各自具體的地址信息殉簸。
畫個圖闰集,更明確的表達下:
直接指針
使用直接指針訪問的話,reference中存儲的就是對象的實際內存地址般卑,不過在Java堆中的對象需要考慮如何去存儲類型數(shù)據的信息武鲁。
畫個圖,更明確的表達下:
對于這兩種方式來說蝠检,具體使用哪一種沐鼠,由實際的虛擬機決定。就HotSpot來說蝇率,使用的是直接指針形式來實現(xiàn)對對象的訪問迟杂。
不過,就這兩種方式來說本慕,各有各的優(yōu)勢排拷。使用句柄的好處,就是當實際對象被移動時锅尘,棧幀中的指向無需改變监氢,只需要修改句柄中的指向即可,棧幀中的變量存儲這穩(wěn)定的內存地址藤违。
直接指針的好處浪腐,是棧幀中的變量直接指向了Java堆中實際的內存地址,訪問速度更快顿乒,節(jié)省了一次指針定位的時間開銷议街。
京東購買鏈接:可伸縮服務架構-框架與中間件