Java虛擬機(jī)把他管理的內(nèi)存分成幾個不同的數(shù)據(jù)區(qū)域-來源<深入了解java虛擬機(jī)>
如圖:
程序計數(shù)器:
“程序計數(shù)器(Program Counter Register)是一塊較小的內(nèi)存空間磕谅,它可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器咧纠。在虛擬機(jī)的概念模型里(僅是概念模型突诬,各種虛擬機(jī)可能會通過一些更高效的方式去實(shí)現(xiàn))厘贼,字節(jié)碼解釋器工作時就是通過改變這個計數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令,分支蜒程、循環(huán)、跳轉(zhuǎn)伺帘、異常處理昭躺、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個計數(shù)器來完成∥奔蓿”
Java虛擬機(jī)棧:
“與程序計數(shù)器一樣领炫,Java虛擬機(jī)棧(Java Virtual Machine Stacks)也是線程私有的,它的生命周期與線程相同张咳。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個方法在執(zhí)行的同時都會創(chuàng)建一個棧幀(Stack Frame[1])用于存儲局部變量表驹吮、操作數(shù)棧、動態(tài)鏈接晶伦、方法出口等信息。每一個方法從調(diào)用直至執(zhí)行完成的過程啄枕,就對應(yīng)著一個棧幀在虛擬機(jī)棧中入棧到出棧的過程婚陪。”
“經(jīng)常有人把Java內(nèi)存區(qū)分為堆內(nèi)存(Heap)和棧內(nèi)存(Stack)频祝,這種分法比較粗糙泌参,Java內(nèi)存區(qū)域的劃分實(shí)際上遠(yuǎn)比這復(fù)雜脆淹。這種劃分方式的流行只能說明大多數(shù)程序員最關(guān)注的、與對象內(nèi)存分配關(guān)系最密切的內(nèi)存區(qū)域是這兩塊沽一。其中所指的“堆”筆者在后面會專門講述盖溺,而所指的“棧”就是現(xiàn)在講的虛擬機(jī)棧铣缠,或者說是虛“擬機(jī)棧中局部變量表部分烘嘱。
局部變量表存放了編譯期可知的各種基本數(shù)據(jù)類型(boolean、byte蝗蛙、char蝇庭、short、int捡硅、float哮内、long、double)壮韭、對象引用(reference類型北发,它不等同于對象本身,可能是一個指向?qū)ο笃鹗嫉刂返囊弥羔樑缥荩部赡苁侵赶蛞粋€代表對象的句柄或其他與此對象相關(guān)的位置)和returnAddress類型(指向了一條字節(jié)碼指令的地址)琳拨。”
本地方法棧:
“本地方法棧(Native Method Stack)與虛擬機(jī)棧所發(fā)揮的作用是非常相似的逼蒙,它們之間的區(qū)別不過是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù)从绘,而本地方法棧則為虛擬機(jī)使用到的Native方法服務(wù)。在虛擬機(jī)規(guī)范中對本地方法棧中方法使用的語言是牢、使用方式與數(shù)據(jù)結(jié)構(gòu)并沒有強(qiáng)制規(guī)定僵井,因此具體的虛擬機(jī)可以自由實(shí)現(xiàn)它。甚至有的虛擬機(jī)(譬如Sun HotSpot虛擬機(jī))直接就把本地方法棧和虛擬機(jī)棧合二為一驳棱∨玻”
Java堆:
“對于大多數(shù)應(yīng)用來說,Java堆(Java Heap)是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊社搅。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域驻债,在虛擬機(jī)啟動時創(chuàng)建。此內(nèi)存區(qū)域的唯一目的就是存放對象實(shí)例形葬,幾乎所有的對象實(shí)例都在這里分配內(nèi)存合呐。這一點(diǎn)在Java虛擬機(jī)規(guī)范中的描述是:所有的對象實(shí)例以及數(shù)組都要在堆上分配[1],但是隨著JIT編譯器的發(fā)展與逃逸分析技術(shù)逐漸成熟笙以,棧上分配淌实、標(biāo)量替換[2]優(yōu)化技術(shù)將會導(dǎo)致一些微妙的變化發(fā)生,所有的對象都分配在堆上也漸漸變得不是那么“絕對”了〔鹌恚”
方法區(qū):
“方法區(qū)(Method Area)與Java堆一樣恨闪,是各個線程共享的內(nèi)存區(qū)域,它用于存儲已被虛擬機(jī)加載的類信息放坏、常量咙咽、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)淤年。雖然Java虛擬機(jī)規(guī)范把方法區(qū)描述為堆的一個邏輯部分钧敞,但是它卻有一個別名叫做Non-Heap(非堆),目的應(yīng)該是與Java堆區(qū)分開來互亮±缦恚”
運(yùn)行時常量池:
“運(yùn)行時常量池(Runtime Constant Pool)是方法區(qū)的一部分。Class文件中除了有類的版本豹休、字段炊昆、方法、接口等描述信息外威根,還有一項信息是常量池(Constant Pool Table)凤巨,用于存放編譯期生成的各種字面量和符號引用,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運(yùn)行時常量池中存放洛搀「易拢”