【JVM學習資料之虛擬機棧中都有什麼?】

虛擬機棧中都有什麼?程序員

Java虛擬機棧(Java Virtual Machine Stacks) 是線程私有的,它的生命週期與線程相同。虛擬機棧爲虛擬機執行Java方法(也就是字節碼)服務,虛擬機棧描述的是Java方法執行的內存 模型:每一個方法在執行的同時都會建立一個棧幀(Stack Frame)用於存儲局部變量表、操做數棧、動態連接、方法出口等信息。每個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中入棧到出棧的過程常常有人把Java內存區分爲堆內存(Heap)和棧內存(Stack),這種方法比較粗糙,Java內存區域的劃分實際上遠比這複雜。數據結構

這種劃分方式的流行只能說明大多數程序員最關注的、與對象內存分配分配關係最密切的內存區域是這兩塊。其中所指的「堆」筆者在後面會專門講述,而所指的「棧」就是如今講的虛擬機棧,或者說是虛擬機棧中局部變量表部分局部變量表存放了編譯期可知的各類基本數據類型(boolean、byte、char、short、int、float、long、double)、對象引用(reference類型,它不等同於對象自己,多是一個指向對象起始地址的引用指針,也多是指向一個表明對象的句柄或其餘與此對象相關的位置)和returnAddress類型(指向了一條字節碼指令的地址)。其中64位長度的long和double類型的數據會佔用2個局部變量空間(Slot),其他的數據類型只佔用1個。局部變量表所需的內存空間在編譯期間完成分配,當進入一個方法時,這個方法須要在幀中分配多大的局部變量空間是徹底肯定的,在方法運行期間不會改變局部變量表的大小。線程

在Java虛擬機規範中,對這個區域規定了兩種異常狀況:若是線程請求的棧深度大於虛擬機所容許的深度,將拋出StackOverflowError異常:若是虛擬機棧能夠動態擴展(當前大部分的Java虛擬機均可動態擴展,只不過Java虛擬機規範中也容許固定長度的虛擬機棧),若是擴展時沒法申請到足夠的內存,就會拋出OutOfMemoryError異常。指針

 

運行時棧幀結構對象

棧幀(Stack Frame)是用於支持虛擬機進行方法調用和方法執行的數據結構,它是虛擬機運行時數據區中的虛擬機棧(Virtual Machine Stack)的棧元素。棧幀存儲了方法的局部變量表、操做數棧、動態連接和方法返操做數棧、動態連接和方法返回地址等信息。每個方法從調用開始至執行完成的過程,都對應着一個棧幀在虛擬機棧裏面從入棧到出棧的過程。每一個棧幀都包括了局部變量表、操做數棧、動態連接、方法返回地址和一些額外的附加信息。在編譯程序代碼的時候,棧幀中須要多大的局部變量表,多深的操做數棧都已經徹底肯定了,而且寫入到方法表的Code屬性之中,所以一個棧幀須要分配多少內存,不會受到程序運行期變量數據的影響,而僅僅取決於具體的虛擬機實現。一個線程中的方法調用鏈可能會很長,不少方法都同時處於執行狀態。對於執行引擎來講,在活動線程中,只有位於棧頂的棧幀纔是有效的,稱爲當前棧幀(Current Stack Frame),與這個棧幀相關聯的方法稱之爲當前方法(Current Method)。執行引擎運行的全部字節碼指令都只針對當前棧幀進行操做,生命週期

 

局部變量表(Local Variable Table)是一組變量值存儲空間,用於存放方法參數和方法內部定義的局部變量。在Java程序編譯爲Class文件時,就在方法Code屬性的max_locals數據項中肯定了該方法所須要分配的局部變量表的最大容量。局部變量表的容量以變量槽(Variable,下稱Slot)爲最小單位,虛擬機規範中並無明確指明一個Slot應占用的內存空間大小,只是頗有導向性地說到每一個Slot都應該能存放一個boolean、byte、char、short、int、float、reference或returnAddress類型的數據,這8種數據類型,均可以使用32位或更小的物理內存來存放,但這種描述與明確指出「每一個Slot佔用32位長度的內存空間」內存



做者:小凡_8c8f
連接:https://www.jianshu.com/p/484ffd69604b
來源:簡書
簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。虛擬機

相關文章
相關標籤/搜索