棧幀
是一種數(shù)據(jù)結(jié)構(gòu)瞒窒,用于支持方法調(diào)用和方法執(zhí)行慌盯。
- 存儲(chǔ)了方法的局部變量表、操作數(shù)棧囊嘉、動(dòng)態(tài)鏈接格嘁、方法返回信息
- 每一個(gè)方法從調(diào)用開(kāi)始至執(zhí)行完成的過(guò)程笛求,都對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧里面從入棧道出棧的過(guò)程
- 一個(gè)棧幀需要分配多少內(nèi)存,不會(huì)受道程序運(yùn)行期變量數(shù)據(jù)的影響,而僅僅取決于具體的虛擬機(jī)實(shí)現(xiàn)
- 在活動(dòng)線程中探入,只有位于棧頂?shù)臈攀怯行У慕瓶祝蔀楫?dāng)前棧幀,與這個(gè)棧幀相關(guān)聯(lián)的方法稱為當(dāng)前方法蜂嗽。執(zhí)行引擎運(yùn)行的所有字節(jié)碼指令都只針對(duì)當(dāng)前棧幀進(jìn)行操作苗膝。
局部變量表
是一組變量值存儲(chǔ)空間,用于存放方法參數(shù)和方法內(nèi)定義的局部變量植旧。
- 不和類變量存在“準(zhǔn)備階段”辱揭。類變量有兩次賦值,一次是在準(zhǔn)備階段病附,賦予系統(tǒng)初始值问窃,一次是在初始化階段,賦予程序員定義的初始值胖喳。因此在初始化階段程序員沒(méi)有為類變量賦值也沒(méi)關(guān)系泡躯,類變量仍然具有一個(gè)確定的初始值贮竟。但局部變量不一樣丽焊,如果局部變量定義了但是沒(méi)有賦初始值,是不能使用的
- 不要認(rèn)為Java中任何情況下都存在諸如整型變量默認(rèn)為0咕别,布爾類型變量默認(rèn)值為false等著用的初始值
操作數(shù)棧
也稱為操作棧技健,后入先出(那不就是先入后出嗎)
- 當(dāng)一個(gè)方法剛剛開(kāi)始執(zhí)行的時(shí)候,這個(gè)方法的操作棧是空的惰拱,在方法的執(zhí)行過(guò)程中雌贱,會(huì)有各個(gè)字節(jié)碼指令往操作棧中寫入和讀取內(nèi)容,這就是出棧/入棧操作
動(dòng)態(tài)鏈接
每個(gè)棧幀都包含有一個(gè)指向運(yùn)行時(shí)常量池中該棧幀所屬方法的引用偿短,持有這個(gè)引用是為了支持方法調(diào)用過(guò)程中的動(dòng)態(tài)鏈接欣孤。
方法返回地址
一個(gè)方法執(zhí)行后,只有兩種方法退出昔逗,一種是遇到任何一個(gè)方法返回的字節(jié)碼指令降传,另一種是執(zhí)行過(guò)程中遇到了異常。(沒(méi)有返回值的咋算勾怒?返回空也算是返回沒(méi))
- 方法退出后需要返回到方法被調(diào)用的位置婆排,程序才能繼續(xù)執(zhí)行,方法返回時(shí)可能需要在棧幀中保存一些信息笔链,用來(lái)幫助恢復(fù)她的上層方法執(zhí)行狀態(tài)段只。一般來(lái)說(shuō),方法正常退出時(shí)鉴扫,調(diào)用者的PC計(jì)算器的值可以作為方法地址赞枕,棧幀中可能會(huì)保存這個(gè)計(jì)數(shù)器的值。而方法異常退出,返回地址是要通過(guò)異常處理器表來(lái)確定的炕婶,棧幀中一般不會(huì)保存這個(gè)信息
- 方法退出的過(guò)程實(shí)際就等同于把當(dāng)前棧幀出棧谍椅,因此退出時(shí)可能執(zhí)行的操作有:恢復(fù)上層的局部變量表和操作數(shù)棧,把返回值(如果有的話)壓入調(diào)用者棧幀的操作棧中古话,跳轉(zhuǎn)PC計(jì)數(shù)器的值以指向方法調(diào)用指令后面的一條指令等雏吭。
附加信息
虛擬機(jī)規(guī)范運(yùn)行具體的虛擬機(jī)實(shí)現(xiàn)增加一些規(guī)范里沒(méi)有描述的信息到棧幀中,例如相關(guān)調(diào)試等信息