JVM內(nèi)存模型

github上的地址:DevelopBlog

概覽

java虛擬機(jī)(以下簡(jiǎn)稱JVM)多種多樣,其中都必須遵循《java虛擬機(jī)規(guī)范》的要求,本篇文章只討論hotspot(SE7).
JVM在運(yùn)行程序時(shí),會(huì)把內(nèi)存劃分為幾個(gè)不同的區(qū)域,以方便線程的切換,GC,內(nèi)存的高效利用等,java運(yùn)行時(shí)數(shù)據(jù)區(qū)域示意圖如下:

運(yùn)行時(shí)數(shù)據(jù)區(qū)域示意圖.png

其中方法區(qū)為線程共享的區(qū)域

程序計(jì)數(shù)器

首先了解一下.class文件結(jié)構(gòu):
當(dāng)我們使用javac命令將.java文件編譯為.class文件之時(shí),編譯器將類的各項(xiàng)信息按照《java虛擬機(jī)規(guī)范》中的規(guī)范一次寫(xiě)入.class文件,其中包括ava版本信息,包名,類信息,字段信息,方法信息等。其中方法塊內(nèi)容將被編譯成為可被JVM識(shí)別的一條條字節(jié)碼指令
JVM執(zhí)行某一方法時(shí)咱台,加載.class文件之后,JVM的字節(jié)碼解釋器讀取文件中的操作指令(一條指令包含操作碼與操作數(shù)),讀取一條執(zhí)行一條俭驮,在多線程任務(wù)不斷切換中回溺,如何才能記錄下各個(gè)線程的切換前的某一方法執(zhí)行的進(jìn)度呢?程序計(jì)數(shù)器就是為此而生混萝,用來(lái)記錄正在執(zhí)行的JVM的字節(jié)碼的指令地址遗遵。由于它記錄的是某一條線程的執(zhí)行進(jìn)度,故他也是線程獨(dú)享的逸嘀。

虛擬機(jī)棧

此部分即我們經(jīng)常提起的java堆棧中的车要。他的生性周期與線程相同,虛擬機(jī)中存儲(chǔ)是以棧幀為單位的崭倘,棧幀是虛擬機(jī)棧的的元素翼岁,在JVM執(zhí)行一新的方法時(shí),JVM會(huì)創(chuàng)建一個(gè)棧幀司光,該棧幀入棧琅坡,方法執(zhí)行結(jié)束后,該棧幀出残家。
棧幀用來(lái)存儲(chǔ)線程執(zhí)行過(guò)程時(shí)方法中的局部變量表榆俺,操作數(shù)棧,方法出口等其他信息跪削。
局部變量表即是我們經(jīng)常討論的部分谴仙,他存儲(chǔ)了基礎(chǔ)類型(int,double碾盐,boolean等),對(duì)象引用(不是對(duì)象本身揩局,而是一個(gè)對(duì)象的內(nèi)存地址)和returnAddress地址(前面提到的字節(jié)碼指令的地址)毫玖。
如圖所示:

線程,虛擬機(jī)棧,棧幀

本地方法棧

虛擬機(jī)棧類似付枫,區(qū)別在于它用來(lái)在虛擬機(jī)執(zhí)行Native方法時(shí)使用

java開(kāi)發(fā)中經(jīng)常提及的烹玉,JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)域中最大的一塊,它的唯一作用就是存放實(shí)例化后的對(duì)象以及數(shù)組阐滩。同時(shí)也是GC的主要區(qū)域二打。虛擬機(jī)棧中存儲(chǔ)了堆中對(duì)象的指針地址。
GC垃圾回收采用分代的思想來(lái)管理內(nèi)存掂榔,在內(nèi)存回收的角度來(lái)看继效,堆分為老年代新生代
新生代是指新創(chuàng)建的對(duì)象装获,老年代是指存活時(shí)間比較長(zhǎng)瑞信,經(jīng)過(guò)多輪GC任然存活的對(duì)象。

老年代穴豫,新生代

先介紹一下兩種GC類型:
新生代GC(Minor GC):指發(fā)生在新生代的垃圾回收凡简,因?yàn)閖ava中大多數(shù)的java對(duì)象存活時(shí)間都不會(huì)很長(zhǎng),具備朝生夕滅的特點(diǎn)精肃,所以Minor GC的回收速度特別快秤涩,也特別頻繁。
老年代GC(Major GC/Full GC):指發(fā)生帶老年代的GC司抱,大多數(shù)情況下會(huì)伴隨發(fā)生至少一次的新生代GC(Minor GC)溉仑,由于使用不同的垃圾回收算法,故而回收速度非常慢状植。
(關(guān)于GC的算法以及常見(jiàn)垃圾回收器浊竟,將在另一篇文章中講解)

新生代是如何晉升為老年代呢?

參照上圖:
Survivor分為兩個(gè)區(qū)域津畸,被稱為S0S1振定,兩個(gè)區(qū)域總有一個(gè)是空閑的。

步驟如下:

  • 新出生的對(duì)象優(yōu)先存活在Eden區(qū)域(Eden不夠時(shí)肉拓,發(fā)起一次Minor GC)后频,java在每個(gè)對(duì)象創(chuàng)建時(shí),為每個(gè)對(duì)象定義了一個(gè)年齡計(jì)數(shù)器暖途,用于標(biāo)記一個(gè)對(duì)象的存活時(shí)間卑惜。

  • 第一次Minor GC新生代GC發(fā)生之后,如果該對(duì)象仍然存活驻售,他的年齡+1露久,并將它從Eden移至Survivor中de S0區(qū)域(這時(shí)EdenS1區(qū)域?yàn)榭眨?/p>

*當(dāng)再次發(fā)生 Minor GC時(shí),此時(shí)回收的區(qū)域?yàn)?code>Eden和S0區(qū)域欺栗,此時(shí)S0區(qū)域沒(méi)有被回收的對(duì)象年齡+1毫痕。此時(shí)重點(diǎn)來(lái)了征峦!S0對(duì)象有兩個(gè)去處,如果達(dá)到最大年齡(默認(rèn)15)的對(duì)象直接移動(dòng)到老年代中消请,沒(méi)有到達(dá)年齡的對(duì)象的對(duì)象全部移至S1區(qū)域,S0清空栏笆;而Eden和上一步驟同樣,存活對(duì)象移至S1如下圖:

image.png

此次GC完成之后,S0Eden為空 如下圖

image.png

此后臊泰,

再次發(fā)生GC之后蛉加,EdenS1發(fā)生回收,將對(duì)象移至S0中缸逃,完成之后针饥,EdenS1為空;

再次發(fā)生GC之后察滑,EdenS0發(fā)生回收打厘,將對(duì)象移至S1中,完成之后贺辰,EdenS0為空户盯;

依此循環(huán),直至年齡達(dá)到一定程度(默認(rèn)15)饲化,對(duì)象進(jìn)入老年代莽鸭。

年齡最大值默認(rèn)為15, 可以通過(guò)參數(shù) -XX MaxTenuringThreshold 設(shè)置

方法區(qū)

方法區(qū)
他存儲(chǔ)的是已經(jīng)被JVM加載的類信息吃靠,常量池硫眨,靜態(tài)變量,JVM即使編譯器等數(shù)據(jù)巢块,同樣也是線程共享區(qū)域礁阁。他經(jīng)常被看成是的邏輯部分,為了方便這部分內(nèi)存管理族奢,JVM將垃圾回收范圍擴(kuò)展至方法區(qū)姥闭,在GC中被稱為永久區(qū)(上圖中的Permanent),故而他經(jīng)常被稱為非堆越走,與java堆進(jìn)行區(qū)分棚品。
GC對(duì)此部分的回收主要集中在對(duì)常量池的回收以及類型的卸載。

常量池

常量池是方法區(qū)的一部分廊敌,用于存放由javac編譯時(shí)生成的.class文件中的常量(例如:包名铜跑,類名,方法名骡澈,字段名锅纺,String字符串等,如下圖)急膀。

class文件中字節(jié)碼常量類型

著作權(quán)歸作者所有聚请。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)膛壹,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處涡拘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疼电,一起剝皮案震驚了整個(gè)濱河市嚼锄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蔽豺,老刑警劉巖区丑,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異修陡,居然都是意外死亡沧侥,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門魄鸦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宴杀,“玉大人,你說(shuō)我怎么就攤上這事拾因⊥眨” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵绢记,是天一觀的道長(zhǎng)扁达。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蠢熄,這世上最難降的妖魔是什么跪解? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮签孔,結(jié)果婚禮上叉讥,老公的妹妹穿的比我還像新娘。我一直安慰自己饥追,他們只是感情好图仓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著判耕,像睡著了一般透绩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上壁熄,一...
    開(kāi)封第一講書(shū)人閱讀 51,258評(píng)論 1 300
  • 那天帚豪,我揣著相機(jī)與錄音,去河邊找鬼草丧。 笑死狸臣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的昌执。 我是一名探鬼主播烛亦,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼诈泼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了煤禽?” 一聲冷哼從身側(cè)響起铐达,我...
    開(kāi)封第一講書(shū)人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎檬果,沒(méi)想到半個(gè)月后瓮孙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡选脊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年杭抠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恳啥。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡偏灿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钝的,到底是詐尸還是另有隱情翁垂,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布扁藕,位于F島的核電站沮峡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏亿柑。R本人自食惡果不足惜邢疙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望望薄。 院中可真熱鬧疟游,春花似錦、人聲如沸痕支。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)卧须。三九已至另绩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間花嘶,已是汗流浹背笋籽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留椭员,地道東北人车海。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像隘击,于是被迫代替她去往敵國(guó)和親侍芝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子研铆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354