談到Java內(nèi)存模型,指的就是運(yùn)行時數(shù)據(jù)區(qū),按照線程是否共享可按圖示劃分
1.程序計數(shù)器:可以看作當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器咕村,它是邏輯計數(shù)器场钉,不是物理的,通過改變計數(shù)器的值來選取下一條要執(zhí)行的指令懈涛,每個線程有獨立的計數(shù)器逛万,只為java方法計數(shù),不發(fā)生內(nèi)存泄漏
2.虛擬機(jī)棧:描述的是java方法執(zhí)行時的線程模型批钠,包含了單個線程每個方法執(zhí)行的棧幀宇植,棧幀存儲了局部變量表,操作數(shù)棧埋心,動態(tài)鏈接指郁,方法出口等信息,每一個方法被調(diào)用直至執(zhí)行完畢的過程拷呆,對應(yīng)著一個棧幀在虛擬機(jī)棧中從入棧到出棧的過程
①局部變量表:包含方法執(zhí)行過程中的所有變量
②操作數(shù)棧:負(fù)責(zé)入棧闲坎、出棧等操作
該內(nèi)存規(guī)定了兩種異常:遞歸引發(fā)的StackOverflowError(遞歸過深,棧楨數(shù)超過虛擬棧深度)和虛擬機(jī)棧過多引發(fā)的OutOfMemoryError(當(dāng)虛擬機(jī)椦笕可以動態(tài)擴(kuò)展時箫柳,如果無法申請足夠多的內(nèi)存,就會拋出異常)
3.本地方法棧:與虛擬機(jī)棧發(fā)揮的作用是相似的啥供,區(qū)別只是虛擬機(jī)棧為虛擬機(jī)執(zhí)行java方法服務(wù),本地方法棧為Native(本地方法)服務(wù)
4.Java堆: Java堆是被所有線程共享的一塊內(nèi)存區(qū)域库糠,在虛擬機(jī)啟動時創(chuàng)建伙狐。此內(nèi)存區(qū)域的唯一目的就是存放對象實例,邏輯上連續(xù)瞬欧,物理上可不連續(xù)贷屎,既可以被實現(xiàn)成固定大小的,也可以設(shè)置成可擴(kuò)展的艘虎。當(dāng)類加載器讀取了類文件后唉侄,需要把類、方法野建、常量属划、變量放到堆內(nèi)存中恬叹,保存所有引用類型的真實信息,以方便執(zhí)行器執(zhí)行同眯。
常量池:存放編譯器生成的字面量和符號引用量
JVM三大性能調(diào)優(yōu)參數(shù)-Xms -Xmx -Xss
在調(diào)用java指令執(zhí)行程序時绽昼,通過傳入以上三個參數(shù)分別調(diào)整java堆以及線程所占內(nèi)存的大小
5.元空間:存儲的是運(yùn)行環(huán)境必須的類信息,取代永久代须蜗,不在Java虛擬機(jī)的堆中實現(xiàn)硅确,而是使用本機(jī)物理內(nèi)存實現(xiàn)。
補(bǔ)充:在Java8中明肮,永久代已經(jīng)被移除菱农,被一個稱為元空間的區(qū)域所取代。元空間的本質(zhì)和永久代類似柿估。
元空間與永久代之間最大的區(qū)別在于:永久代使用的JVM的堆內(nèi)存(但是邏輯上是非堆的)大莫,但是java8以后的元空間并不在虛擬機(jī)中而是使用本機(jī)物理內(nèi)存(所以在上圖中,我用虛線表示)官份。
永久代:是一個常駐內(nèi)存的區(qū)域只厘,用于存放JDK自身所攜帶的Class,Interface的元數(shù)據(jù)舅巷,即存儲的是運(yùn)行環(huán)境必須的類信息羔味,被轉(zhuǎn)載進(jìn)此區(qū)域的數(shù)據(jù)是不會被垃圾回收的,只有關(guān)閉JVM才會釋放此區(qū)域所占用的內(nèi)存空間钠右。
元空間:取代永久代赋元,不在Java虛擬機(jī)的堆中實現(xiàn),而是使用本機(jī)物理內(nèi)存實現(xiàn)飒房。默認(rèn)情況下元空間大小僅受本地內(nèi)存限制搁凸。類的元數(shù)據(jù)放入native memory,字符串常量在Java堆中(運(yùn)行時常量和基本類型常量在元空間——方法區(qū))
PS:jdk1.8狠毯,jvm把字符串常量池移到了堆內(nèi)存里护糖。此時方法區(qū)=元空間
方法區(qū)(Method Area)并不是所謂的存儲方法的區(qū)域,而是供各線程共享的運(yùn)行時內(nèi)存區(qū)域嚼松。它存儲了已被虛擬機(jī)加載的類信息嫡良、方法信息、字段信息献酗、常量(被final修飾)寝受、靜態(tài)變量、即時編譯器編譯后的代碼緩存等罕偎。
方法區(qū)也是一種規(guī)范很澄,在不同虛擬機(jī)里頭實現(xiàn)是不一樣的,最典型的實現(xiàn)就是HotSpot虛擬機(jī)Java8之前的永久代(PermGen space)和Java8的元空間(Metaspace)。