Java 內(nèi)存區(qū)域與內(nèi)存溢出異常
翻越虛擬機(jī)內(nèi)存管理的第一步:了解Java虛擬機(jī)內(nèi)存的各個(gè)區(qū)域的作用、服務(wù)對(duì)象以及可能產(chǎn)生的問(wèn)題杈帐。
運(yùn)行時(shí)數(shù)據(jù)區(qū)域
1、程序計(jì)數(shù)器
由于Java虛擬機(jī)的多線程是通過(guò)線程輪流切換并分配處理器執(zhí)行時(shí)間的方式來(lái)實(shí)現(xiàn)的,在任何一個(gè)確定的時(shí)刻如蚜,一個(gè)處理器都只會(huì)執(zhí)行一條線程中的指令择镇。因此挡逼,為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程都需要有一個(gè)獨(dú)立的程序計(jì)數(shù)器腻豌,各條線程之間計(jì)數(shù)器互不影響家坎,獨(dú)立存儲(chǔ),我們稱這類內(nèi)存區(qū)域?yàn)椤熬€程私有”的內(nèi)存吝梅。 此內(nèi)存區(qū)域是唯一一個(gè)在Java虛擬機(jī)規(guī)范中沒(méi)有規(guī)定任何OutOfMemoryError情況的區(qū)域虱疏。
2、Java虛擬機(jī)棧
線程私有的內(nèi)存區(qū)域苏携, 生命周期與線程相同做瞪。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表、操作數(shù)棧右冻、動(dòng)態(tài)鏈接装蓬、方法出口等信息。每個(gè)方法從調(diào)用直至執(zhí)行完成的過(guò)程纱扭,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中入棧到出棧的過(guò)程牍帚。
在Java虛擬機(jī)規(guī)范中,對(duì)這個(gè)區(qū)域規(guī)定了兩種異常:如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度乳蛾,將拋出StackOverflowError異常暗赶;如果虛擬機(jī)棧的動(dòng)態(tài)擴(kuò)展無(wú)法申請(qǐng)到足夠的內(nèi)存,將會(huì)拋出OutOfMemoryError異常肃叶。
3蹂随、本地方法棧
4、Java堆
對(duì)于大多數(shù)應(yīng)用來(lái)說(shuō)因惭,Java堆是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊岳锁。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)是創(chuàng)建筛欢。