本分享內(nèi)容基于《深入了解Java虛擬機(jī)》(第二版)的內(nèi)容敏沉,基于JDK1.7诊沪,基于HotSpot虛擬機(jī)差导。
運(yùn)行時(shí)數(shù)據(jù)區(qū)域
程序計(jì)數(shù)器
這是一塊較小的內(nèi)存空間,主要用于當(dāng)前線(xiàn)程鎖所執(zhí)行的字節(jié)碼的行號(hào)帜消。字節(jié)碼解釋器通過(guò)改變計(jì)數(shù)器選取下一條需要執(zhí)行的字節(jié)碼指令棠枉。分支、循環(huán)泡挺、跳轉(zhuǎn)术健、異常處理、線(xiàn)程恢復(fù)都需要計(jì)數(shù)器粘衬。
多線(xiàn)程在處理器中通過(guò)線(xiàn)程輪流切換來(lái)執(zhí)行,所以每個(gè)線(xiàn)程都需要單獨(dú)程序計(jì)數(shù)器來(lái)恢復(fù)到正確的執(zhí)行位置咳促。
執(zhí)行Java方法:記錄正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址稚新。
執(zhí)行Native方法:計(jì)數(shù)器值為空。
唯一一個(gè)不存在OutOfMemoryError情況的區(qū)域跪腹。
Java虛擬機(jī)棧
線(xiàn)程私有褂删,生命周期與線(xiàn)程相同。每個(gè)方法執(zhí)行都會(huì)創(chuàng)建一個(gè)棧幀冲茸,用于存儲(chǔ)局部變量表屯阀、操作數(shù)棧、動(dòng)態(tài)鏈接轴术、方法出口等信息难衰。
局部變量表:存儲(chǔ)基本數(shù)據(jù)類(lèi)型、對(duì)象引用(1逗栽、指向?qū)ο笃鹗嫉囊弥羔?2盖袭、執(zhí)行代表對(duì)象的句柄 3、其他與此對(duì)象相關(guān)的位置)彼宠、retrunAddress類(lèi)型(指向了一條字節(jié)碼指令的地址)
局部變量表所需的內(nèi)存空間在編譯期間完成鳄虱,運(yùn)行過(guò)程中不會(huì)改變。
該區(qū)域存在兩種異常狀況:
1凭峡、如果線(xiàn)程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度拙已,將拋出StackOverflowError異常;
2摧冀、如果虛擬機(jī)棻蹲伲可以動(dòng)態(tài)擴(kuò)展系宫,如果擴(kuò)展時(shí)無(wú)法申請(qǐng)到足夠的內(nèi)存,就會(huì)拋出OutOfMemoryError異常惭适;
本地方法棧
本地方法棧與虛擬機(jī)棧的作用類(lèi)似笙瑟,主要區(qū)別在于本地方法棧作用于調(diào)用Native方法。
部分虛擬機(jī)會(huì)把本地方法棧與虛擬機(jī)棧合二為一癞志。
拋出的異常與虛擬機(jī)棧一樣往枷。
Java堆
Java虛擬機(jī)最大內(nèi)存一塊,被所有線(xiàn)程共享的一塊內(nèi)存區(qū)域凄杯。
所有的對(duì)象實(shí)例以及數(shù)組都要在堆上分配错洁。(棧上分配、標(biāo)量替換等技術(shù)導(dǎo)致并不是所有對(duì)象都分配到堆上)
本區(qū)域采用分代收集算法戒突,包含Eden空間屯碴、From Survivor空間、To Survivor空間膊存。里面會(huì)劃分出多個(gè)線(xiàn)程私有的分配緩沖區(qū)导而。
該區(qū)域如果沒(méi)有足夠內(nèi)存分配,則會(huì)拋出OutOfMemoryError異常隔崎。
方法區(qū)
方法區(qū)是各線(xiàn)程共享的內(nèi)存區(qū)域今艺。存儲(chǔ)虛擬機(jī)加載的類(lèi)信息、常量爵卒、靜態(tài)變量虚缎、即時(shí)編譯后的代碼等數(shù)據(jù)。
該區(qū)域如果沒(méi)有足夠內(nèi)存分配钓株,則會(huì)拋出OutOfMemoryError異常实牡。
注意:方法區(qū)和永久代不是同一個(gè)東西。(字符常量池已從永生代移出)
運(yùn)行時(shí)常量池
用于存放編譯生成的各種字面量和符號(hào)引用(類(lèi)加載過(guò)程中一種狀態(tài))轴合。
常量池重要特性:動(dòng)態(tài)性--運(yùn)行期間也可以將新的常量加入池中创坞。( String類(lèi)的intern()方法 )
該區(qū)域如果沒(méi)有足夠內(nèi)存分配,則會(huì)拋出OutOfMemoryError異常受葛。
直接內(nèi)存
直接內(nèi)存不是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)部分摆霉,但是也會(huì)拋出OutOfMemoryError異常。
NIO類(lèi):引入一種基于通道與緩沖區(qū)的I/O方式奔坟,使用Native函數(shù)庫(kù)直接分配堆外內(nèi)存携栋。(DirectByteBuffer操作這塊內(nèi)存,避免Java堆和Native堆之間復(fù)制數(shù)據(jù))
直接內(nèi)存的分配不會(huì)受到Java堆大小的限制咳秉。