0.概論
推薦書目:深入理解Java虛擬機(jī)
java虛擬機(jī)內(nèi)存主要分為三部分:java虛擬機(jī)棧荧恍,java堆稠茂,靜態(tài)方法區(qū)
1.java虛擬機(jī)棧
其中java虛擬機(jī)棧就是我們俗稱的棧內(nèi)存,其中主要存放的是8種基本類型和對(duì)象的引用错览,這一部分為線程私有部分棚贾,當(dāng)請(qǐng)求的棧深度大于java虛擬機(jī)棧所允許的深度,jvm將拋出StackOverflowError異常
java中的引用可以理解為c++中的指針
2.java堆
java堆空間主要存放的就是java程序運(yùn)行過程中所產(chǎn)生的對(duì)象啦吧,而如果需要使用對(duì)象則需要先從棧內(nèi)存中拿到引用,通過引用來指向?qū)?nèi)存中的對(duì)象拙寡,而通過引用來操作對(duì)象也有兩種方式(句柄方式和直接指針)授滓,其中java堆是各個(gè)線程共享的,因此在操作對(duì)象的過程中我們需要使用鎖來鎖住對(duì)象倒庵,避免多線程中產(chǎn)生的數(shù)據(jù)不一致問題褒墨,當(dāng)對(duì)象大小總和超過jvm分配的對(duì)內(nèi)存大小時(shí)jvm會(huì)拋出OutOfMemoryError異常
圖中的對(duì)象實(shí)例數(shù)據(jù)就是jvm中對(duì)象的成員變量等每個(gè)對(duì)象獨(dú)有的內(nèi)容,而對(duì)象類型數(shù)據(jù)就是類方法等所有對(duì)象相同的部分
堆內(nèi)存中其實(shí)還可以再繼續(xù)細(xì)分擎宝,可以分為年輕代和老年代郁妈,這兩代應(yīng)該通過名字十分好理解,年輕代一般存放年紀(jì)較小的绍申,剛生成沒多久的對(duì)象噩咪,而老年代則主要存放年紀(jì)較大顾彰,生成較久的對(duì)象(關(guān)于java堆中的具體內(nèi)容和jvm的gc策略后面還會(huì)有文章詳細(xì)講解)
3.靜態(tài)方法區(qū)
從該區(qū)域的名字大家其實(shí)就可以大概看出本區(qū)域存儲(chǔ)的內(nèi)容了,即主要存儲(chǔ)的是常量胃碾、靜態(tài)變量和方法涨享,還有一部分為jvm加載的類的信息(即.class文件),這一部分為線程共享的(因?yàn)槊總€(gè)線程都可以同時(shí)調(diào)用同一個(gè)方法嘛)
4.其他部分
啊嘞嘞仆百?不是說jvm主要分為3個(gè)區(qū)域么厕隧?對(duì),但是要注意是主要俄周,其實(shí)jvm還存在幾個(gè)經(jīng)常被人忽略的區(qū)域吁讨,即為:本地方法棧,程序計(jì)數(shù)器
程序計(jì)數(shù)器:當(dāng)前線程執(zhí)行字節(jié)碼的行號(hào)指示器(這是官方解釋峦朗,其實(shí)就是執(zhí)行到代碼的行號(hào))建丧,由于每個(gè)線程執(zhí)行到的代碼行號(hào)都不同,因此這一部分肯定是線程私有的啦
本地方法棧:主要為虛擬機(jī)使用native方法服務(wù)
5.直接內(nèi)存的使用
在java1.4中引入了非阻塞IO模式波势,即NIO翎朱,在我們使用NIO時(shí)會(huì)通過native方法分配直接內(nèi)存,避免在Java堆與native堆中來回復(fù)制數(shù)據(jù)尺铣,提高性能