JVM學習筆記之棧區

amadan發表於2021-09-09

JVM學習筆記之棧區

本文主要內容:

棧是什麼?棧幀又是什麼?在JVM中,main方法呼叫say方法後,是怎麼執行的?本文將詳細講解棧。希望大家學了之後,對棧有更深的瞭解。

心法:在JVM中,棧管執行,堆管儲存。

棧資料結構特點:先進後出。生活中常見的case就是彈夾。最後一個壓進彈夾的子彈,最先出彈夾。

Stack棧:
棧也叫棧記憶體,主管Java程式的執行,是線上程建立時建立,它的生命週期跟隨執行緒的生命週期,執行緒結束,棧記憶體也就被釋放了。對於棧來說,不存在垃圾回收問題,只要是執行緒一結束,該棧就over了。生命週期和執行緒一直的,是執行緒私有的。

8中基本型別的變數+物件的引用變數+例項方法都是在函式的棧記憶體中分配的。

棧中儲存的是什麼?

在瞭解棧之前,先來了解另一個概念:棧幀。

棧幀

棧幀(Stack Frame):用於支援虛擬機器進行方法呼叫和方法執行的資料結構。它是虛擬機器執行時資料區中的虛擬機器棧的棧元素。

棧幀儲存了方法的區域性變數表、運算元棧、動態連線和方法返回地址等資訊。每個方法從呼叫開始至執行完成的過程,都對應這一個棧幀在虛擬機器棧裡面從入棧到出棧的過程。

額,什麼叭叭叭的,說的什麼意思呢?簡單如下:

棧幀中主要儲存3類資料:

本地變數(Local variables):輸入引數和輸出引數以及方法內的變數;

圖片描述

編輯

如上圖中的 int x,int y就是輸入引數

Int result就是輸出引數。

其中的X、Y、result都是方法內的變數

棧操作(Operand Stack):記錄出棧、入棧的操作;

棧幀資料(fram Date):包括類檔案、方法等等。

棧執行的原理:

棧中的資料都是以棧幀的格式存在,棧幀是一個記憶體區塊,是一個資料集,是一個有關方法(Method)和執行期,資料的資料集。

當一個方法A被呼叫的時候,就產生了一個棧幀F1,並被壓到棧中;

A方法呼叫了B方法,於是產生了棧幀F2也被壓入棧中;

B方法又呼叫了C方法,於是產生棧幀F3,也被壓入到棧中;

依次類推。

當執行完畢後,先彈出F3棧幀,在彈出F2棧幀,在彈出F1棧幀。依次類推。

遵循”先進後出/後進先出”的原則。

程式碼演示:

寫個main函式,在main方法中,呼叫say方法。然後檢視輸出結果。

圖片描述

編輯

執行結果:

圖片描述

編輯

當程式執行到3行的時候,呼叫了主執行緒main函式,這個時候產生了棧幀F1,被壓入棧,程式碼繼續向下走;

當程式碼執行到第5行的時候,呼叫了say方法,這個時候產生了棧幀F2,發現後面還有程式碼需要執行,F2就被壓入棧;

當執行第10行的時候,say方法呼叫了showCode方法,這個時候就產生了F3。進入方法showCode方法後,後面還有程式碼,F3壓棧,繼續執行。

當執行到第17行的時候,發現沒有需要執行的了。F3就從棧裡面被彈出棧了;

接著回到say方法裡面,繼續執行,程式走到第12行的時候,發現say方法執行完成了,於是F2就被彈出棧了;

程式回到main方法中,也就是該執行第6行了,執行完第6行,當到底7行的時候,發現主函式也執行了了,於是F1就被彈出棧了;

整個執行緒執行完成,棧區被清空。程式結束。如下圖:

圖片描述

編輯

一個執行緒中的方法呼叫鏈可能會很長,很多方法都同時處於執行狀態。對於執行引擎來說,在活動執行緒中(爭搶到CPU執行權的),只有位於棧頂的棧幀才是有效的,成為當前棧幀(Current Stack Frame),與這個棧幀相關聯的方法稱為當前方法(Current Method)。執行引擎執行的所有位元組碼指令都是隻針對於當前棧幀進行操作的。

棧幀概念模型如下圖:

圖片描述

編輯

需要說明的是:每個方法執行的同時都會建立一個棧幀,用於存放區域性變數表、運算元棧、動態連線、方法返回等等資料。每個方法從被呼叫至執行完成的過程,就對應著一個棧幀在虛擬機器中入棧和出棧的過程。棧的大小和具體JVM的實現有關,通常在256K~756K之間,約等於1Mb左右。

棧+堆+方法區的互動關係

圖片描述

HotSpot是使用指標的方法來訪問物件的:

Java堆中會存放訪問類後設資料的地址,reference存放的就直接是物件的地址。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2310/viewspace-2826293/,如需轉載,請註明出處,否則將追究法律責任。

相關文章