堆內(nèi)存和棧內(nèi)存

我們常常做的是將Java內(nèi)存區(qū)域簡(jiǎn)單的劃分為兩種: 一種叫做棧內(nèi)存,一種叫做堆內(nèi)存。

棧內(nèi)存

棧內(nèi)存又分兩種,一種是虛擬機(jī)棧,一種是本地方法棧。

本地方法棧是去調(diào)用native方法服務(wù),和java關(guān)系不算太大。

虛擬機(jī)棧就牛逼了,它里面存了局部變量表,操作棧,動(dòng)態(tài)鏈接,方法出口等信息。

局部變量表存放了編譯期可知的各種基本數(shù)據(jù)類(lèi)型,對(duì)象引用和一條字節(jié)碼指令的地址。
其中64位長(zhǎng)度的long和double類(lèi)型的數(shù)據(jù)會(huì)占用2個(gè)局部變量空間,其余的基本類(lèi)型占1個(gè)。

當(dāng)進(jìn)入一個(gè)方法時(shí),這個(gè)方法需要分配多大的局部變量空間是完全確定的,在運(yùn)行期間不會(huì)改變變量表的大小。

在java虛擬機(jī)規(guī)范中,這個(gè)區(qū)域會(huì)有兩種異常情況產(chǎn)生,如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度,將會(huì)拋出StackOverflowError異常。如果沒(méi)有處理好遞歸調(diào)用的出口條件,很容易就會(huì)報(bào)這樣的錯(cuò)。

如果虛擬機(jī)棧動(dòng)態(tài)擴(kuò)展的時(shí)候無(wú)法申請(qǐng)最夠的內(nèi)存,就會(huì)拋出OutOfMemoryError異常。

堆內(nèi)存

Java的堆是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊。

堆的唯一目的就是存放對(duì)象實(shí)例。所有的對(duì)象實(shí)例都會(huì)在這里分配內(nèi)存。

堆產(chǎn)生了一個(gè)對(duì)象之后,還能夠在棧里面定義一個(gè)變量指向堆的的首地址。
如果這個(gè)對(duì)象沒(méi)有被引用,那么不一會(huì)就會(huì)被java當(dāng)作垃圾回收,因此Java堆是垃圾收集的管理主要區(qū)域。

如果在堆中沒(méi)有內(nèi)存完成實(shí)例分配,并且堆也無(wú)法再擴(kuò)展時(shí),將會(huì)拋出OutOfMemoryError異常。

參考資料

深入理解java虛擬機(jī)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容