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ū)域隨著線程的開(kāi)始和結(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)是用來(lái)存儲(chǔ)數(shù)據(jù)和部分過(guò)程結(jié)果的數(shù)據(jù)結(jié)構(gòu)莽使,同時(shí)也被用來(lái)處理動(dòng)態(tài)鏈接(Dynamic Linking)锐极、方法返回值和異常分派(Dispatch Exception)。
- 棧幀隨著方法調(diào)用而創(chuàng)建芳肌,隨著方法結(jié)束而銷毀——無(wú)論方法是正常完成還是異常完成(拋出了在方法內(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)語(yǔ)言中的編譯代碼儲(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)語(yǔ)言中符號(hào)表(SymbolTable)的角色,不過(guò)它存儲(chǔ)數(shù)據(jù)范圍比通常意義上的符號(hào)表要更為廣泛右锨。
每一個(gè)運(yùn)行時(shí)常量池都分配在 Java 虛擬機(jī)的方法區(qū)之中括堤,在類和接口被加載到虛擬機(jī)后,對(duì)應(yīng)的運(yùn)行時(shí)常量池就被創(chuàng)建出來(lái)。
六,本地方法棧---與線程相關(guān)
Java 虛擬機(jī)實(shí)現(xiàn)可能會(huì)使用到傳統(tǒng)的棧(通常稱之為“C Stacks”)來(lái)支持 native 方法(指使用 Java 以外的其他語(yǔ)言編寫的方法)的執(zhí)行悄窃,這個(gè)棧就是 本地方法棧(Native Method Stack)讥电。當(dāng) Java 虛擬機(jī)使用其他語(yǔ)言(例如 C 語(yǔ)言)來(lái)實(shí)現(xiàn)指令集解釋器時(shí),也會(huì)使用到 地方法棧轧抗。如果 Java 虛擬機(jī)不支持 natvie 方法恩敌,并且自己也不依賴傳統(tǒng)棧的話,可以無(wú)需支持 地方法棧鸦致,如果支持 地方法棧潮剪,那這個(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ī)范>>