每當啟動一個新線程的時候,java虛擬機都會為它分配一個java棧。java以棧幀為單位保存線程的運行狀態(tài)。虛擬機只會對java棧執(zhí)行兩種操作:以棧幀為單位的壓棧或者出棧。
java方法可以通過兩種方式完成,一種通過return返回,成為正常返回;一種通過拋出異常而異常終止 。虛擬機都會將當前棧彈出java棧然后釋放掉,這樣上一個方法的棧幀就是當前棧幀了。
java棧上是此對應的java線程所私有的。因此不存在多線程情況下棧數(shù)據(jù)訪問同步的問題。
棧幀由三部分組成:局部變量區(qū),操作數(shù)棧和幀數(shù)據(jù)區(qū)。 局部變量區(qū)和操作數(shù)棧要視對應的方法而定,它們是按照字長計算的。
局部變量區(qū): java棧幀的局部變量區(qū)被組織為一個以字長為單位,從0開始計數(shù)的數(shù)組。字節(jié)碼指令通過從0開始的索引來使用其中的數(shù)據(jù)。類型為int,float,reference和returnaddress的值在數(shù)組中只占一項,而類型為byte,short和char的值在存入數(shù)組前都將被轉換為int。但是long和double類型在數(shù)組中卻占據(jù)連續(xù)的兩項。
操作數(shù)棧和局部變量區(qū)一樣。也被組織成一個以字長為單位的數(shù)組。但是不是通過索引來訪問,而是通過標準棧操作--壓棧和出棧來訪問。
不同于程序計數(shù)器,java虛擬機沒有寄存器,程序計數(shù)器也無法被程序指令直接訪問。java虛擬機是由操作數(shù)棧而不是從寄存器中取得操作數(shù)的,因此它的運行方式是基于棧的而不是基于寄存器的。
虛擬機把操作數(shù)棧作為它的工作區(qū)--大多數(shù)指令都要從這里彈出數(shù)據(jù),執(zhí)行運算,然后把結果壓回操作數(shù)棧。