昨天跟大家聊過了關(guān)于JVM的程序計數(shù)器的細(xì)節(jié)實現(xiàn)涯竟。相比大家覺得程序計數(shù)器也不過如此吧。其實技術(shù)本無難點庐船。故若高深也會讓人感覺虛無縹緲。落入實地其實也就了了揩瞪。
那今天我們開始介紹JVM的第二個重要的組成部分——棧(JAVA STACK)。
棧是什么
棧是和線程一致的內(nèi)存空間且線程私有李破。也就是說它的生命周期是和線程是一致的壹将。當(dāng)一個方法開始執(zhí)行的時候會同事在棧空間里面創(chuàng)建一個棧幀【Stack Frame】來存儲局部變量表诽俯、操作數(shù)棧、動態(tài)鏈接暴区、方法出口等信息。
每一個方法從調(diào)用直至執(zhí)行完成的過程其實在棧中都是有一個對應(yīng)的棧幀在虛擬機棧中同樣的入棧到出棧的過程偷俭。
棧的數(shù)據(jù)結(jié)構(gòu)
局部變量表:中的局部變量表存放了編譯期可知的各種基本數(shù)據(jù)類型(boolean缰盏、char淹遵、short、int透揣、float川抡、long辐真、double)注意:long和double是64位的長度崖堤,要占用2個局部變量空間。其余數(shù)據(jù)類型只要占用1個密幔。
對象引用(reference類型,它不等同于對象本身昧廷,可能是一個指向?qū)ο笃鹗嫉刂返囊弥羔樫梭铮部赡苁侵赶蛞粋€代表對象的句柄或其他與此對象相關(guān)的位置)和returnAddress類型(指向了一條字節(jié)碼指令的地址)木柬。
動態(tài)鏈接:在運行時創(chuàng)建的直接引用稱為動態(tài)鏈接淹办。即程序在編譯成.class文件后會有一系列的引用。這些是靜態(tài)引用齐遵。而在運行時才創(chuàng)建的引用稱為動態(tài)引用。
方法出口:方法出口分為兩種。第一種方式是執(zhí)行引擎遇到任意一個方法返回的字節(jié)碼指令拓哟,這時候可能會有返回值傳遞給上層的方法調(diào)用者;另外一種退出方式是流纹,在方法執(zhí)行過程中遇到了異常,并且這個異常沒有在方法體內(nèi)得到處理漱凝,無論是Java虛擬機內(nèi)部產(chǎn)生的異常诸迟,還是代碼中使用athrow字節(jié)碼指令產(chǎn)生的異常茸炒,只要在本方法的異常表中沒有搜索到匹配的異常處理器,就會導(dǎo)致方法退出感论。
棧的異常
如果線程請求的棧深度大于虛擬機所允許的深度紊册。會拋出StackOverFlowError異常比肄。
如果虛擬機棧擴展是無法申請到足夠的內(nèi)存囊陡,就會拋出OutOfMemioryError異常
今天對于棧的分析就是以上的內(nèi)容。以上內(nèi)容其實還沒有深入到虛擬機中棧的數(shù)據(jù)結(jié)構(gòu)的實現(xiàn)示括。但是對于了解JVM棧的結(jié)構(gòu)和狀態(tài)已經(jīng)是足夠滿足要求了。各位如果有補充的可以留言交流垛膝。也希望各位不吝賜教丁稀。今天的內(nèi)容就到這里了吼拥。明天還有對于JVM的后續(xù)介紹线衫。
我的文章每天都會在頭條號首發(fā),然后第二天轉(zhuǎn)發(fā)到簡書中枯跑,希望有興趣的朋友可以關(guān)注我的頭條號:[Bug制造機]
(https://www.toutiao.com/c/user/51553105950/#mid=1582105392193550)。謝謝大家的支持敛助。