JVM學習:虛擬機棧-局部變量表

認識局部變量表


  1. 局部變量表:Local Variables,被稱之為局部變量數組或本地變量表。
  2. 定義為一個數字數組,主要用于存儲方法參數和定義在方法體內的局部變量,這些數據類型包括各類基本數據類型、對象引用(reference),以及returnAddress類型
    • 八大基本數據類型都可以轉換為數字。
  3. 由于局部變量表是建立在線程的棧上(棧幀內),是線程的私有數據,因此不存在數據安全問題。
  4. 局部變量表所需的容量大小是在編譯期確定下來的,并保存在方法的Code屬性的maximum local variables數據項中。在方法運行期間是不會改變局部變量表的大小的。
  5. 方法嵌套調用的次數由棧的大小決定。一般來說,方法嵌套調用次數越多,棧越大。
    • 對一個函數而言,它的參數和局部變量越多,使得局部變量表膨脹,它的棧幀就越大,以滿足方法調用所需傳遞的信息增大的需求。
    • 進而函數調用就會占用更多的棧空間,導致其嵌套調用次數就會減少。
  6. 局部變量表中的變量只在當前方法調用中有效。
    • 在方法執行時,虛擬機通過使用局部變量表完成參數值到參數變量列表的傳遞過程。
    • 當方法調用結束后,隨著方法棧幀的銷毀,局部變量表也會隨之銷毀。

總結

  • 棧是由多個棧幀(方法)組成。
  • 若固定棧的大小,則最上層棧幀超出限制后會拋出StackoverflowError異常。
  • 覺得棧幀大小最主要部分是局部變量表。
  • 局部變量表大小編譯時就已確認,比如方法內定義十個對象,大小為10,而不是十個對象的內存大小。(相對來講10)
問題:局部變量表大小編譯時確定,為什么編譯時不能確定是否會棧溢出呢?
  • 方法調用伴隨著出棧入棧,編譯期不會確定棧內存在多少棧幀。
  • 只是確認了棧幀內的局部變量表大小。不是整個棧內容都確定。

關于 Slot (變量槽)的理解

  1. 參數值的存放總是從局部變量數組索引 0 的位置開始,到數組長度-1的索引結束。
  2. 局部變量表,最基本的存儲單元是Slot(變量槽),局部變量表中存放編譯期可知的各種基本數據類型(8種),引用類型(reference),returnAddress類型的變量。
  3. 在局部變量表里,32位以內的類型只占用一個slot(包括returnAddress類型),64位的類型占用兩個slot(long和double)
  4. JVM會為局部變量表中的每一個Slot都分配一個訪問索引,通過這個索引即可成功訪問到局部變量表中指定的局部變量值。
  5. 當一個實例方法被調用的時候,它的方法參數和方法體內部定義的局部變量將會按照順序被復制到局部變量表中的每一個slot上
  6. 如果需要訪問局部變量表中一個64bit的局部變量值時,只需要使用前一個索引即可。(比如:訪問long或double類型變量)
  7. 如果當前幀是由構造方法或者實例方法創建的,那么該對象引用this將會存放在index為0的slot處,其余的參數按照參數表順序繼續排列。

總結

  • long和double占兩個槽,其他占一個。
  • 如果訪問的是非實例方法(即類的方法)那么第0位表示的就是this。static方法無this。
  • 分配順序:this變量->方法中的其他形參->方法內部定義的局部變量。

代碼實操

image.png

[圖片上傳中...(image.png-317529-1606998517442-0)]

  • Start與Length組成變量作用域。
  • Slot為局部變量所占槽位,若圖中num替換為double或long類型,則num的下一個槽位將從4開始。

非static方法存在this局部變量,static方法則不存在


image.png

Solt的重復利用

棧幀中的局部變量表中的槽位是可以重用的,如果一個局部變量過了其作用域那么在其作用域之后申明新的局部變量變就很有可能會復用過期局部變量的槽位,從而達到節省資源的目的。

public void test4() {
    int a = 0;
    { int b = 0;   b = a + 1;
    }
    //變量c使用之前已經銷毀的變量b占據的slot的位置
    int c = a + 1;
}
局部變量 c 重用了局部變量 b 的 slot 位置
image.png

補充說明

  1. 類變量表有兩次初始化的機會,第一次是在鏈接中的“準備階段”,執行系統初始化,對類變量設置零值(final修飾的static不會),另一次則是在“初始化”階段,賦予程序員在代碼中定義的初始值
  2. 和類變量初始化不同的是,局部變量表不存在系統初始化的過程,這意味著一旦定義了局部變量則必須人為的初始化,否則無法使用(編譯不會通過)。
  3. 在棧幀中,與性能調優關系最為密切的部分就是局部變量表。在方法執行時,虛擬機使用局部變量表完成方法的傳遞。
  4. 局部變量表中的變量也是重要的垃圾回收根節點,只要被局部變量表中直接或間接引用的對象都不會被回收。
個人補充:

學到此處,一直迷惑與不同類間方法調用流程,出入棧的順序,具體誰來掌控,想了一天,有些思路,以下僅代表個人粗略觀點,謹慎借鑒。

  1. 設想目前有兩個類,One類里面包含一個mian方法,Two類里面包含一個Add求和方法。main方法需要傳參調用Add方法。
  2. 單個文件編譯,先One則報錯,因為需要調用的Add方法的類未進行編譯。一般都是直接編譯整個項目,所以不會出現這個問題。
    • Error:(16, 9) java: 找不到符號 符號: 類 JvmBeginTest 位置: 類 fangk.jvm.CshTest
  3. 兩文件編譯完成之后,每個類的字節碼文件中,方法(棧幀)的局部變量表大小確定(根據參數和內部定義變量),只是大小不是內容。
    • 同樣確認的還有操作數棧深度、字節碼長度(指令集)。
  4. 確認的只是些代碼編譯能確認的。
  5. 運行main方法,相當于啟動一個線程,PC寄存器先記錄main方法的第一步,假設共10步,在第五步時調用Add方法。
  6. 前五步執行時在第一個棧幀內,棧幀內的局部變量表或其他會等待調用的Add棧幀執行完,繼續執行第六步。
  7. PC寄存器來記錄下一步的指令,調用方法時,會把被調用的方法入到棧頂,執行完出棧。繼續執行調用方法的棧幀。
  8. 說的不明白,理解的不太透徹,改天專門寫個博客記錄。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容