JVM——Java棧

每當啓動一個新線程時,Java虛擬機都會爲它分配一個Java棧。Java棧以幀爲單位保存線程的運行狀態。虛擬機只會直接對Java棧執行兩個操作:以幀爲單位的壓棧或出棧。當線程調用一個Java方法時,虛擬機都會在該線程的Java棧中壓入一個新棧。

棧幀:

棧幀由三部分組成:局部變量,操作數棧和棧數據區。

當虛擬機調用一個Java方法時,它從對應類的信息中得到此方法的局部變量和操作數據棧的大小,並據此分配棧幀內存,然後壓入Java棧中。

1)局部變量:Java棧幀的局部變量區被組織爲一個以字節爲單位,從0開始計數的數組。

2)操作數棧:和局部變量一樣,被組織成一個字長爲單位的數組。通過標準的棧操作——壓棧和出棧來訪問。

3)棧數據區:Java棧中支持常量池解析,正常方法返回以及異常派發機制的一些信息。

例子:

一個斐波那契序列的代碼,如下:

class Fibonacci {

    static void calcSequence() {
        long fiboNum = 1;
        long a = 1;
        long b = 1;

        for (;;) {
            fiboNum = a + b;
            a = b;
            b = fiboNum;
        }
    }
}
指令碼:

 0 lconst_1   // Push long constant 1
 1 lstore_0   // Pop long into local vars 0 & 1: long a = 1;
 2 lconst_1   // Push long constant 1
 3 lstore_2   // Pop long into local vars 2 & 3: long b = 1;
 4 lconst_1   // Push long constant 1
 5 lstore 4   // Pop long into local vars 4 & 5: long fiboNum = 1;
 7 lload_0    // Push long from local vars 0 & 1
 8 lload_2    // Push long from local vars 2 & 3
 9 ladd       // Pop two longs, add them, push result
10 lstore 4   // Pop long into local vars 4 & 5: fiboNum = a + b;
12 lload_2    // Push long from local vars 2 & 3
13 lstore_0   // Pop long into local vars 0 & 1: a = b;
14 lload 4    // Push long from local vars 4 & 5
16 lstore_2   // Pop long into local vars 2 & 3: b = fiboNum;
17 goto 7     // Jump back to offset 7: for (;;) {}

虛擬機鏡像:

1)初始化。Local Variables:局部變量。Operand Stack:操作數棧。


2)分配3個變量:fiboNum,a,b。局部變量是一個3位的數組。


3)lload_0:從局部變量0中裝載long類型值,lload_2:從局部變量2中裝載long類型值。


4)ladd:執行int類型的加法。


5)istore 4:從棧中彈出int類型值,然後將其存到位置爲4的局部變量中。





參考資料:

《深入Java虛擬機》


發佈了50 篇原創文章 · 獲贊 15 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章