我們知道在java中創(chuàng)建對(duì)象最簡(jiǎn)單的方式就是 new 但是 在這簡(jiǎn)單的new之后,jvm到底是怎么給我們這個(gè)實(shí)例對(duì)象分配內(nèi)存的,
1首先我們要理解jvm中的內(nèi)存模型jvm中內(nèi)存模型從大了說觅闽,主要分為棧內(nèi)存忌愚,堆內(nèi)存揍鸟,當(dāng)然還有一些其他的包括寄存器妒穴,線程棧等等,今天我重點(diǎn)說一下堆內(nèi)存結(jié)構(gòu)模型
堆內(nèi)存里面在細(xì)分新生代寒矿,舊生代鹦聪,新生代包括一個(gè)eden區(qū)和兩個(gè)survivo區(qū)
當(dāng)申請(qǐng)新對(duì)象的時(shí)候內(nèi)存申請(qǐng)過程如下:
a、jvm先嘗試在eden區(qū)分配新建對(duì)象所需的內(nèi)存充坑;
b减江、如果內(nèi)存大小足夠,申請(qǐng)結(jié)束捻爷,否則下一步辈灼;
c、jvm啟動(dòng)youngGC也榄,試圖將eden區(qū)中不活躍的對(duì)象釋放掉巡莹,釋放后若Eden空間仍然不足以放入新對(duì)象,則試圖將部分Eden中活躍對(duì)象放入Survivor區(qū);
d降宅、Survivor區(qū)被用來作為Eden及old的中間交換區(qū)域骂远,當(dāng)OLD區(qū)空間足夠時(shí),Survivor區(qū)的對(duì)象會(huì)被移到Old區(qū)腰根,否則會(huì)被保留在Survivor區(qū)激才;
e、?當(dāng)OLD區(qū)空間不夠時(shí)唠雕,JVM會(huì)在OLD區(qū)進(jìn)行full GC;
f吨述、full GC后岩睁,若Survivor及OLD區(qū)仍然無法存放從Eden復(fù)制過來的部分對(duì)象,導(dǎo)致JVM無法在Eden區(qū)為新對(duì)象創(chuàng)建內(nèi)存區(qū)域揣云,則出現(xiàn)”out of memory錯(cuò)誤”:
outOfMemoryError:javaheap space
2?方法區(qū)內(nèi)存溢出(outOfMemoryError:permgem space)
在jvm規(guī)范中捕儒,方法區(qū)主要存放的是類信息、常量邓夕、靜態(tài)變量等刘莹。
所以如果程序加載的類過多,或者使用反射焚刚、gclib等這種動(dòng)態(tài)代理生成類的技術(shù)点弯,就可能導(dǎo)致該區(qū)發(fā)生內(nèi)存溢出,一般該區(qū)發(fā)生內(nèi)存溢出時(shí)的錯(cuò)誤信息為:
outOfMemoryError:permgem space
線程棧溢出(java.lang.StackOverflowError)
線程棧時(shí)線程獨(dú)有的一塊內(nèi)存結(jié)構(gòu)矿咕,所以線程棧發(fā)生問題必定是某個(gè)線程運(yùn)行時(shí)產(chǎn)生的錯(cuò)誤抢肛。
一般線程棧溢出是由于遞歸太深或方法調(diào)用層級(jí)過多導(dǎo)致的。
發(fā)生棧溢出的錯(cuò)誤信息為:
java.lang.StackOverflowError