更新時(shí)間:2020-10-09 17:30:54 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1518次
JVM棧,全稱(chēng)為Java 虛擬機(jī)棧,線(xiàn)程私有,生命周期和線(xiàn)程一致。描述的是 Java 方法執(zhí)行的內(nèi)存模型:每個(gè)方法在執(zhí)行時(shí)都會(huì)床創(chuàng)建一個(gè)棧幀(Stack Frame)用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息。每一個(gè)方法從調(diào)用直至執(zhí)行結(jié)束,就對(duì)應(yīng)著一個(gè)棧幀從虛擬機(jī)棧中入棧到出棧的過(guò)程。
當(dāng)程序開(kāi)始執(zhí)行時(shí),由于只有一個(gè)main線(xiàn)程,因而JVM只需要為main線(xiàn)程分配好棧區(qū)的內(nèi)存(話(huà)句話(huà)說(shuō)如果有多個(gè)線(xiàn)程,自然就會(huì)有多個(gè)棧區(qū),并且為各自線(xiàn)程私有)。main繼續(xù)執(zhí)行,就會(huì)遇到main()方法,遇到之后呢!JVM又會(huì)在棧區(qū)當(dāng)中再劃出一個(gè)小塊來(lái)存放main()方法執(zhí)行過(guò)程的數(shù)據(jù),這一小塊區(qū)域也就是棧幀。main()方法執(zhí)行過(guò)程中又有一個(gè)add()方法出現(xiàn)了,同樣地,JVM又會(huì)再為add()分配一個(gè)棧幀,同時(shí)壓入到棧區(qū),以后再遇到其他方法也是如此。當(dāng)然,方法在執(zhí)行完成之后,便會(huì)彈出并釋放內(nèi)存,當(dāng)線(xiàn)程中棧區(qū)的所有方法都返回之后,程序也就算是執(zhí)行完畢了。
當(dāng)我們扯開(kāi)棧區(qū),撕開(kāi)棧幀,一不小心,局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口......嘩啦啦地散落一地。
撿起add()棧幀的局部變量表和操作數(shù)棧就可以看到這樣一個(gè)畫(huà)面,在執(zhí)行例子中add()方法中的三行代碼時(shí),局部變量表和操作數(shù)棧的一個(gè)變化過(guò)程:首先,執(zhí)行int a = 3;局部變量表中會(huì)分配出一個(gè)int區(qū)域,表示為a;同時(shí)iconst命令使得操作數(shù)棧中壓入了常量3,然后再由istore命令將3彈出,賦值給局部變量表中a。同樣,int b = 4; 這一行代碼也是如此。然后,int c = a + b;從右往左開(kāi)始,先執(zhí)行a + b,也就是iload命令從局部變量中取出a、b對(duì)應(yīng)的值,再將iadd后的值push進(jìn)操作數(shù)棧中,剩下的便是int c = 7的操作了。
通過(guò)上面的例子,就很容易明白;局部變量表,顧名思義就是存放每個(gè)方法中的局部變量(即編譯器可知的各種基本類(lèi)型(boolean、byte、char、short、int、float、long、double)、對(duì)象引用(reference 類(lèi)型)和 returnAddress 類(lèi)型(指向了一條字節(jié)碼指令的地址))所在處,如圖中的a、b。操作數(shù)棧,也就是存放的就是方法當(dāng)中的各種操作數(shù)的臨時(shí)空間,又如栗子中的3、4。
動(dòng)態(tài)鏈接:Class文件的常量池中存在有大量的符號(hào)引用,字節(jié)碼中的方法調(diào)用指令就以指向常量池的引用作為參數(shù),而將部分符號(hào)引用在運(yùn)行期間轉(zhuǎn)化為直接引用,這種轉(zhuǎn)化即為動(dòng)態(tài)鏈接。這個(gè)解釋當(dāng)中會(huì)涉及到許多概念,比如常量池、符號(hào)引用等,要想理解這些概念,就需要去了解class文件的結(jié)構(gòu),內(nèi)容太多就不在這里詳細(xì)描述了。
方法出口:簡(jiǎn)單來(lái)說(shuō),就是用于標(biāo)記當(dāng)前方法執(zhí)行完成之后,應(yīng)該返回到下一條指令執(zhí)行位置。比如就上面的栗子而言,add()在執(zhí)行完畢之后,就應(yīng)該返回到e1.add()之后繼續(xù)執(zhí)行main()后面的代碼。
上面就是對(duì)JVM棧的全面講解,還沒(méi)有完全弄懂的小伙伴可以通過(guò)觀(guān)看本站的Java零基礎(chǔ)教程學(xué)習(xí)更多的JVM知識(shí)。
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話(huà)與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743