1、虛擬機棧(VM Stack)
1.1)什麼是虛擬機棧
虛擬機棧是用於描述java方法執行的內存模型。
每一個java方法在執行時,會建立一個「棧幀(stack frame)」,棧幀的結構分爲「局部變量表、操做數棧、動態連接、方法出口」幾個部分(具體的做用會在字節碼執行引擎章節中講到,這裏只須要了解棧幀是一個方法執行時所須要數據的結構)。咱們常說的「堆內存、棧內存」中的「棧內存」指的即是虛擬機棧,確切地說,指的是虛擬機棧的棧幀中的局部變量表,由於這裏存放了一個方法的全部局部變量。
方法調用時,建立棧幀,並壓入虛擬機棧;方法執行完畢,棧幀出棧並被銷燬,以下圖所示:
1.2)虛擬機棧的特色
虛擬機棧是線程隔離的,即每一個線程都有本身獨立的虛擬機棧。
1.3)虛擬機棧的StackOverflowError
若單個線程請求的棧深度大於虛擬機容許的深度,則會拋出StackOverflowError(棧溢出錯誤)。
JVM會爲每一個線程的虛擬機棧分配必定的內存大小(-Xss參數),所以虛擬機棧可以容納的棧幀數量是有限的,若棧幀不斷進棧而不出棧,最終會致使當前線程虛擬機棧的內存空間耗盡,典型如一個無結束條件的遞歸
函數調用,代碼見下:
設置單個線程的虛擬機棧內存大小爲128K,執行main方法後,拋出了StackOverflow異常
1 Stack length:983
2 java.lang.StackOverflowError
3 at com.manayi.study.jvm.chapter2._02_JavaVMStackSOF.stackLeak(_02_JavaVMStackSOF.java:14)
4 at com.manayi.study.jvm.chapter2._02_JavaVMStackSOF.stackLeak(_02_JavaVMStackSOF.java:15)
5 at com.manayi.study.jvm.chapter2._02_JavaVMStackSOF.stackLeak(_02_JavaVMStackSOF.java:15)
6 ······
1.4)虛擬機棧的OutOfMemoryError
不一樣於StackOverflowError,OutOfMemoryError指的是當
整個虛擬機棧內存耗盡,而且沒法再申請到新的內存時拋出的異常。
JVM未提供設置整個虛擬機棧佔用內存的配置參數。虛擬機棧的最大內存大體上等於「JVM進程能佔用的最大內存(依賴於具體操做系統) - 最大堆內存 - 最大方法區內存 - 程序計數器內存(能夠忽略不計) - JVM進程自己消耗內存」。當虛擬機棧可以使用的最大內存被耗盡後,便會拋出OutOfMemoryError,能夠經過不斷開啓新的線程來模擬這種異常,代碼以下:
設置單個線程虛擬機棧的佔用內存爲2m並不斷生成新的線程,最終虛擬機棧沒法申請到新的內存,拋出異常:
1 Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
2、本地方法棧(Native Method Stack)
本地方法棧的功能和特色相似於虛擬機棧,均具備線程隔離的特色以及都能拋出StackOverflowError和OutOfMemoryError異常。
不一樣的是,本地方法棧服務的對象是JVM執行的native方法,而虛擬機棧服務的是JVM執行的java方法。如何去服務native方法?native方法使用什麼語言實現?怎麼組織像棧幀這種爲了服務方法的數據結構?虛擬機規範並未給出強制規定,所以不一樣的虛擬機實能夠進行自由實現,咱們經常使用的HotSpot虛擬機選擇合併了虛擬機棧和本地方法棧。