JVM那些事兒(二)-----JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)

Java虛擬機(jī)定義了若干種程序運(yùn)行期間會(huì)使用到的運(yùn)行時(shí)數(shù)據(jù)區(qū),其中有一些會(huì)隨著虛擬機(jī)啟動(dòng)而創(chuàng)建,隨著虛擬機(jī)退出而銷毀.另外一些是與線程一一對(duì)應(yīng)的,這些與線程對(duì)應(yīng)的數(shù)據(jù)區(qū)域隨著線程的開始和結(jié)束而創(chuàng)建和銷毀

一,PC寄存器---與線程相關(guān)

Java 虛擬機(jī)可以支持多條線程同時(shí)執(zhí)行,每一條 Java虛擬機(jī)線程都有自己的 PC(Program Counter)寄存器。在任意時(shí)刻,一條 Java 虛擬機(jī)線程只會(huì)執(zhí)行一個(gè)方法的代碼,這個(gè)正在被線程執(zhí)行的方法稱為該線程的當(dāng)前方法。如果這個(gè)方法不是 native 的,那 PC 寄存器就保存 Java 虛擬機(jī)正在執(zhí)行的字節(jié)碼指令的地址,如果該方法是 native 的,那 PC 寄存器的值是 undefined。PC 寄存器的容量至少應(yīng)當(dāng)能保存一個(gè) returnAddress 類型的數(shù)據(jù)或者一個(gè)與平臺(tái)相關(guān)的 地指針的值。

二,Java虛擬機(jī)棧和棧幀---與線程相關(guān)
  • 1,Java虛擬機(jī)棧(JVM Stack)
    每一條 Java 虛擬機(jī)線程都有自己私有的 Java 虛擬機(jī)棧(Java Virtual Machine Stack),這個(gè)棧與線程同時(shí)創(chuàng)建,用于存儲(chǔ)棧幀

  • 2,棧幀(Frame)

    • 棧幀(Frame)是用來存儲(chǔ)數(shù)據(jù)和部分過程結(jié)果的數(shù)據(jù)結(jié)構(gòu),同時(shí)也被用來處理動(dòng)態(tài)鏈接(Dynamic Linking)、方法返回值和異常分派(Dispatch Exception)。
    • 棧幀隨著方法調(diào)用而創(chuàng)建,隨著方法結(jié)束而銷毀——無論方法是正常完成還是異常完成(拋出了在方法內(nèi) 被捕獲的異常)都算作方法結(jié)束。棧幀的存儲(chǔ)空間分配在 Java 虛擬機(jī)棧之中,每一個(gè)棧幀都有自己的局部變量表(Local Variables)、操作數(shù)棧(OperandStack)和指向當(dāng)前方法所屬的類的運(yùn)行時(shí)常量池的引用。
    • 在一條線程之中,只有目前正在執(zhí)行的那個(gè)方法的棧幀是活動(dòng)的。這個(gè)棧幀就被稱為是當(dāng)前棧幀(Current Frame),這個(gè)棧幀對(duì)應(yīng)的方法就被稱為是當(dāng)前方法(Current Method),定義這個(gè)方法的類就稱作當(dāng)前類(Current Class)。對(duì)局部變量表和操作數(shù)棧的各種操作,通常都指的是對(duì)當(dāng)前棧幀的對(duì)局部變量表和操作數(shù)棧進(jìn)行的操作。
    • 棧幀是線程 地私有的數(shù)據(jù),不可能在一個(gè)棧幀之中引用另外一條線程的棧幀。
三,Java堆(Heap)---與JVM相關(guān)

Java 堆在虛擬機(jī)啟動(dòng)的時(shí)候就被創(chuàng)建
在 Java 虛擬機(jī)中,堆(Heap)是可供各條線程共享的運(yùn)行時(shí)內(nèi)存區(qū)域,也是供所有類實(shí)例和數(shù)組對(duì)象分配內(nèi)存的區(qū)域。這塊區(qū)域內(nèi)存就是被垃圾回收器所管理的

四,方法區(qū)(Method Area)---與JVM相關(guān)

在 Java 虛擬機(jī)中,方法區(qū)(Method Area)是可供各條線程共享的運(yùn)行時(shí)內(nèi)存區(qū)域.方法區(qū)在虛擬機(jī)啟動(dòng)的時(shí)候被創(chuàng)建,方法區(qū)是堆的邏輯組成部分.
方法區(qū)與傳統(tǒng)語言中的編譯代碼儲(chǔ)存區(qū)(Storage Area Of Compiled Code)或者操作系統(tǒng)進(jìn)程的正文段(Text Segment)的作用非常類似,它存儲(chǔ)了每一個(gè)類的結(jié)構(gòu)信息,常量,靜態(tài)變量,即時(shí)編譯器編譯后的代碼等數(shù)據(jù).例如運(yùn)行時(shí)常量池(Runtime Constant Pool)、字段和方法數(shù)據(jù)、構(gòu)造函數(shù)和普通方法的字節(jié)碼內(nèi)容、還包括一些在類、實(shí)例、接口初始化時(shí)用到的特殊方法。

五,運(yùn)行時(shí)常量池(Runtime Constant Pool)---與JVM相關(guān)

運(yùn)行時(shí)常量池(Runtime Constant Pool)是每一個(gè)類或接口的常量池的運(yùn)行時(shí)表示形式,它包括了若干種不同的常量:從編譯期可知的數(shù)值字面量到必須運(yùn)行期解析后才能獲得的方法或字段引用,例如,存放編譯期生成的各種字面量和符號(hào)引用。運(yùn)行時(shí)常量池扮演了類似傳統(tǒng)語言中符號(hào)表(SymbolTable)的角色,不過它存儲(chǔ)數(shù)據(jù)范圍比通常意義上的符號(hào)表要更為廣泛。
每一個(gè)運(yùn)行時(shí)常量池都分配在 Java 虛擬機(jī)的方法區(qū)之中,在類和接口被加載到虛擬機(jī)后,對(duì)應(yīng)的運(yùn)行時(shí)常量池就被創(chuàng)建出來。

六,本地方法棧---與線程相關(guān)

Java 虛擬機(jī)實(shí)現(xiàn)可能會(huì)使用到傳統(tǒng)的棧(通常稱之為“C Stacks”)來支持 native 方法(指使用 Java 以外的其他語言編寫的方法)的執(zhí)行,這個(gè)棧就是 本地方法棧(Native Method Stack)。當(dāng) Java 虛擬機(jī)使用其他語言(例如 C 語言)來實(shí)現(xiàn)指令集解釋器時(shí),也會(huì)使用到 地方法棧。如果 Java 虛擬機(jī)不支持 natvie 方法,并且自己也不依賴傳統(tǒng)棧的話,可以無需支持 地方法棧,如果支持 地方法棧,那這個(gè)棧一般會(huì)在線程創(chuàng)建的時(shí)候按線

總之

  • 程序計(jì)數(shù)器,JAVA虛擬機(jī)棧(棧幀是存放在JAVA虛擬機(jī)棧中的,隨著方法的調(diào)用而生,方法結(jié)束而消亡),本地方法棧是隨著線程創(chuàng)建而生,線程結(jié)束而消亡.
  • JAVA堆和本地方法區(qū)(運(yùn)行時(shí)常量池是在本地方法區(qū)中的)是隨著虛擬機(jī)啟動(dòng)而創(chuàng)建,隨著虛擬機(jī)結(jié)束而消亡

參考<<JAVA虛擬機(jī)規(guī)范>>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容