JVM之虛擬機棧

一.基本概念

      虛擬機棧描述的是java方法執行的動態內存模型:每個方法從執行都會創建一個棧幀,用來存儲局部變量表,操作數棧,動態鏈接,方法出口等信息。每一個方法從執行到結束,都對應一個棧幀的在虛擬機棧中的入棧和出棧。特點:線程私有。

Class Text{
    public static void sleep(){
        goBed();
        Boolean isSleep = true;
        if(isSleep){
             System.out.println("Sleep....");
        }
         int number1 = 1;
         int number2 = 2;
        int number3 = number1 + number2;
    }
    public static void goBed(){
        Boolean isGobed = true;
        if(isGobed){
            System.out.println("goBed....");
        } 
    }
    
    public static void main(String[] args){
        sleep();
    }
}

 

   以上述程序爲模板其虛擬機棧運行如圖

 

    虛擬機棧遵循LIFO的思想,當main被調用時入棧,當main調用sleep時棧幀2入棧,依次類推。

    當goBed函數執行完,棧幀3出棧,依次類推。

    每次的棧幀入棧操作對應着虛擬機棧的內存消耗,當棧的內存消耗完時,方法則不能進行調用這時便會出現stackOverFlowError,即內存溢出。

    常規下棧的內存是多少呢,每個機器的默認棧內存不大一樣大概2m左右,可以通過定義數組的大小進行估算。當然也可以自己設置棧內存的大小(在後面棧溢出問題將演示).

    棧裏面的變量表和操作數棧他們之間的聯繫是什麼。以棧幀3爲類。

   操作數棧是一個用來保存執行過程中的運算值的功能(LIFO)

   如圖是一個概念演示。

    returnAddress類型是爲字節碼指令jsr、jsr_w和ret服務的,它指向了一條字節碼指令的地址。在Class文件中的常量池持中存有大量的符號引用。字節碼中的方法調用指令就以常量池中指向方法的符號引用作爲參數。這些符號引用一部分在類的加載階段(解析)或第一次使用的時候就轉化爲了直接引用(指向數據所存地址的指針或句柄等),這種轉化稱爲靜態鏈接。而相反的,另一部分在運行期間轉化爲直接引用,就稱爲動態鏈接。 

import java.lang.Integer

public Test{
    
}

java文件編譯時不知道Integer類的真實地址,它加入用Integer這個名詞來代替的話,這個Integer就可以理解爲符號引用,當Test類被裝載器裝載時,通過虛擬機就可以獲得Integr真實的地址,這真實地址就是直接引用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章