一、運(yùn)行時(shí)數(shù)據(jù)區(qū)域
1.1 程序計(jì)數(shù)器
一塊較小的內(nèi)存空間刀诬,可看作當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。字節(jié)碼指示器工作時(shí)就是通過改變這個(gè)計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令钻蹬,分支酷师、循環(huán)佳遣、跳轉(zhuǎn)腮猖、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個(gè)計(jì)數(shù)器來完成懂讯。
如果線程執(zhí)行是一個(gè)Java方法的時(shí)候坛悉,計(jì)數(shù)器記錄的是虛擬機(jī)字節(jié)碼指令的地址伐厌;當(dāng)執(zhí)行的是Native的方法的時(shí)候,計(jì)數(shù)器指令為空裸影;該內(nèi)存區(qū)域是Java虛擬機(jī)唯一沒有規(guī)定任何OutOfMemoryError的區(qū)域挣轨。
1.2 Java虛擬機(jī)棧
線程私有。每個(gè)Java方法在執(zhí)行的同時(shí)轩猩,都會(huì)創(chuàng)建一個(gè)棧幀卷扮,用于存儲(chǔ)局部變量表,操作數(shù)棧均践,動(dòng)態(tài)鏈接晤锹,方法出入口等信息,每個(gè)方法的調(diào)用到執(zhí)行完成的過程就是一個(gè)棧幀入棧到出棧的過程彤委。
局部變量表存放編譯期可知的各種基本數(shù)據(jù)類型鞭铆、對(duì)象引用和returnAddress類型。局部變量表所需的空間在編譯期完成分配焦影,方法運(yùn)行期不會(huì)改變局部變量表的大小车遂。
虛擬機(jī)棧規(guī)定了2種異常情況:
- 線程請(qǐng)求棧的深度大于虛擬機(jī)棧所允許的深度,這時(shí)候?qū)?huì)拋出StackOverflowError異常斯辰,
- 虛擬機(jī)允許動(dòng)態(tài)擴(kuò)展虛擬機(jī)棧艰额,當(dāng)擴(kuò)展的時(shí)候無法申請(qǐng)到足夠內(nèi)存時(shí)就會(huì)報(bào)OutOfMemoryError異常;
1.3 本地方法棧
線程私有椒涯。與Java虛擬機(jī)棧類似柄沮,但是為虛擬機(jī)使用的Native方法服務(wù)。也會(huì)拋StackOverflowError和OutOfMemoryError異常。
1.4 Java堆
所有線程共享祖搓。Java虛擬機(jī)中管理的的內(nèi)存最大的一塊狱意,可以處于物理上不連續(xù)的內(nèi)存空間,只要邏輯上連續(xù)即可拯欧,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建详囤。此內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例,幾乎 所有對(duì)象實(shí)例都在這里分配內(nèi)存镐作。
當(dāng)堆中沒有內(nèi)存完成實(shí)例分配藏姐,并且堆無法擴(kuò)展的時(shí)候,將會(huì)拋出OutOfMemoryError该贾。
1.5 方法區(qū)
所有線程共享羔杨。用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量杨蛋、靜態(tài)變量兜材、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。這塊區(qū)域的內(nèi)存回收目標(biāo)是針對(duì)常量池的回收和對(duì)類型的卸載逞力。
當(dāng)方法區(qū)沒有內(nèi)存空間的時(shí)候就拋出OutOfMemoryError異常曙寡。
1.5.1 運(yùn)行時(shí)常量池
方法區(qū)的一部分。Class文件含有常量池信息寇荧,用于存放編譯期生成的各種字面量和符號(hào)引用举庶,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池中存放。一般還會(huì)把翻譯出來的直接引用也存儲(chǔ)在運(yùn)行時(shí)常量池中揩抡。
運(yùn)行時(shí)常量池具備動(dòng)態(tài)性灯变,運(yùn)行期間也可能將新的常量放入池中。
當(dāng)常量池沒有內(nèi)存空間的時(shí)候就拋出OutOfMemoryError異常捅膘。
1.6 直接內(nèi)存
并非Java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分添祸,也不是JVM規(guī)范中定義的內(nèi)存區(qū)域。但這部分內(nèi)存被頻繁使用寻仗,也可能導(dǎo)致OutOfMemoryError異常刃泌。
二、對(duì)象的創(chuàng)建
- 虛擬機(jī)遇到new指令時(shí)署尤,首先檢查指令的參數(shù)能否在常量池中定位到一個(gè)類的符號(hào)引用耙替,并且檢查這個(gè)符號(hào)引用代表的類是否已經(jīng)被加載、解析和初始化過曹体。若沒有則必須先執(zhí)行相應(yīng)的類加載過程俗扇。
- 在類加載檢查通過后,虛擬機(jī)將為新生對(duì)象分配內(nèi)存