粗談Java虛擬機(jī)之內(nèi)存管理


圖片.png
1.1 Java棧

線程私有,生命周期與線程相同言秸。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個(gè)方法在執(zhí)行時(shí)都會(huì)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表软能、操作數(shù)棧、動(dòng)態(tài)鏈接举畸、方法出口等信息查排。每個(gè)方法從調(diào)用直至執(zhí)行完成的過程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中入棧到出棧的過程抄沮。如果請(qǐng)求的站深度大于虛擬機(jī)所允許的深度跋核,將拋出StackOverflowError異常,虛擬機(jī)棧在動(dòng)態(tài)擴(kuò)展時(shí)如果無法申請(qǐng)到足夠的內(nèi)存叛买,就會(huì)拋出OutOfMemoryError異常砂代。
總結(jié):它存放的是java方法執(zhí)行時(shí)的所有數(shù)據(jù)。 由棧幀組成一個(gè)棧幀代表一個(gè)方法的執(zhí)行率挣。

Java棧幀

每個(gè)方法從調(diào)用到執(zhí)行完成對(duì)應(yīng)一個(gè)棧幀在虛擬機(jī)中的入棧到出棧刻伊。

結(jié)構(gòu)圖:

image

棧幀由局部變量區(qū)、操作數(shù)棧和幀數(shù)據(jù)區(qū)組成椒功。當(dāng)虛擬機(jī)調(diào)用一個(gè)Java方法時(shí),它從對(duì)應(yīng)類的類型信息中得到此方法的局部變量區(qū)和操作數(shù)棧的大小丁屎,并根據(jù)此分配棧幀內(nèi)存旱眯,然后壓入Java棧中节沦。

例如:

public static String A(){
    String str=B();(1)
    return str;
}
public static String B(){
    return "Hellow Word";
}

A方法執(zhí)行時(shí)分配一個(gè)棧幀,當(dāng)(1)處調(diào)用B方法是就會(huì)壓如一個(gè)新的棧幀吼鳞,當(dāng)B()方法結(jié)束赔桌,棧幀彈出。

  • 局部變量區(qū)
    局部變量區(qū)被組織為以字長為單位音诫、從0開始計(jì)數(shù)的數(shù)組竭钝。字節(jié)碼指令通過從0開始的索引使用其中的數(shù)據(jù)香罐。類型為int, float, reference和returnAddress的值在數(shù)組中占據(jù)一項(xiàng)庇茫,而類型為byte, short和char的值在存入數(shù)組前都被轉(zhuǎn)換為int值旦签,也占據(jù)一項(xiàng)寸宏。但類型為long和double的值在數(shù)組中卻占據(jù)連續(xù)的兩項(xiàng)击吱。
    returnAddress這個(gè)基本類型被用來實(shí)現(xiàn)Java程序中的finally子句覆醇,Java程序員不能使用這個(gè)類型,它的值指向一條虛擬機(jī)指令的操作碼袍辞。
    結(jié)構(gòu)圖:

    image

  • 操作數(shù)棧
    和局部變量區(qū)一樣搅吁,操作數(shù)棧也是被組織成一個(gè)以字長為單位的數(shù)組谎懦。它通過標(biāo)準(zhǔn)的棧操作訪問--壓棧和出棧。由于程序計(jì)數(shù)器無法被程序指令直接訪問吸申,Java虛擬機(jī)的指令是從操作數(shù)棧中取得操作數(shù)截碴,所以它的運(yùn)行方式是基于棧而不是基于寄存器日丹。虛擬機(jī)把操作數(shù)棧作為它的工作區(qū)哲虾,因?yàn)榇蠖鄶?shù)指令都要從這里彈出數(shù)據(jù)齐帚,執(zhí)行運(yùn)算对妄,然后把結(jié)果壓回操作數(shù)棧剪菱。

1.2 本地方法棧

與虛擬機(jī)棧類似,不過虛擬機(jī)棧是為虛擬機(jī)執(zhí)行Java方法(字節(jié)碼)服務(wù)旗们,而本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)上渴。該區(qū)域同樣會(huì)報(bào)StackOverflowError
方法區(qū)

1.3 方法區(qū)

用于存儲(chǔ)被Java虛擬機(jī)加載的類信息稠氮、常量隔披、靜態(tài)變量寂拆、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。不同于Java堆的是鬓长,Java虛擬機(jī)規(guī)范對(duì)方法區(qū)的限制非常寬松痢士,可以選擇不實(shí)現(xiàn)垃圾收集(永遠(yuǎn)占據(jù)內(nèi)存)。

常量池:這個(gè)名詞可能大家也經(jīng)常見,它是方法區(qū)的一部分城侧。Class文件除了有類的版本嫌佑、字段侨歉、方法幽邓、接口等描述信息外,還有一項(xiàng)信息就是常量池柒啤,用于存放編譯期生成的各種字面量和符號(hào)引用担巩。(JDK1.7已經(jīng)把常量池轉(zhuǎn)移到堆里面了)

1.4 堆區(qū)

所有通過new對(duì)象的內(nèi)存都在對(duì)中分配;是虛擬機(jī)最大一塊內(nèi)存涛癌,是要GC回收的拳话。這一部分也是重點(diǎn)需要分析的漾脂。

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

一塊較小的內(nèi)存空間骨稿,可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。字節(jié)碼解釋器工作時(shí)就是通過改變這個(gè)計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令形耗,分支激涤、循環(huán)、跳轉(zhuǎn)送滞、異常處理犁嗅、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個(gè)計(jì)數(shù)器完成褂微。此內(nèi)存區(qū)域是唯一一個(gè)在Java虛擬機(jī)規(guī)范中沒有規(guī)定任何OutOfMemoryError情況的區(qū)域宠蚂。(也就是說明其他區(qū)域都可能產(chǎn)生OOM童社,但是我們開發(fā)中重點(diǎn)是根據(jù)堆的原理避免OOM)


2.Java堆區(qū)分析

Java堆是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊叠洗,被進(jìn)程的所有線程共享,在虛擬機(jī)啟動(dòng)時(shí)被創(chuàng)建十艾。該區(qū)域的唯一目的就是存放對(duì)象實(shí)例忘嫉,幾乎所有的對(duì)象實(shí)例都在這里分配內(nèi)存庆冕,Java堆是垃圾收集器管理的主要區(qū)域访递。根據(jù)Java虛擬機(jī)規(guī)范同辣,Java堆可以處于物理上不連續(xù)的內(nèi)存空間,只要邏輯上連續(xù)即可响巢。該區(qū)域的大小可以通過-Xmx和-Xms參數(shù)來擴(kuò)展(這部分不懂)踪古,如果堆中沒有內(nèi)存完成實(shí)例分配伏穆,并且堆也無法擴(kuò)展,將會(huì)拋出OutOfMemoryError異常田弥。

2.1 堆區(qū)內(nèi)存

由于現(xiàn)在的收集器基本都采用分代收集算法,所以Java堆中還可以分為老年代和新生代(Eden商叹、From Survivor剖笙、To Survivor)

clipboard.png

(一般服務(wù)器需要修改 移動(dòng)端不太需要修改)

3. 垃圾回收原理

3.1 垃圾收集算法
3.1.1 引用計(jì)數(shù)算法(jdk1.2以前)

引用計(jì)數(shù)算法只要可達(dá) 有被引用就+1 就不會(huì)被回收

圖片.png
3.1.2 引用計(jì)數(shù)算法(下面幾種都是jdk1.2以后)

之間的連線關(guān)系是通過引用來實(shí)現(xiàn)關(guān)聯(lián)的过蹂。

圖片.png

既然提到了引用不得不提四大引用類型:

圖片.png

clipboard.png

這部分我一直沒有找到比較好的文章,自己本身也理解不好脆诉。后期有機(jī)會(huì)會(huì)找找書籍與實(shí)踐好好研究下另寫文章贷币。
參考1
參考2

3.2 垃圾回收算法

通過收集算法役纹。將垃圾對(duì)象回收J(rèn)VN虛擬機(jī)也是用過一些算法進(jìn)行處理掉垃圾的。

3.2.1 標(biāo)記-清楚算法
clipboard.png
3.2.1 復(fù)制算法
clipboard.png
3.2.1 標(biāo)記整理算法

標(biāo)記整理算法是對(duì)標(biāo)記-清楚算法做了一些調(diào)整策州,當(dāng)掃描到不被引用的對(duì)象的時(shí)候 它和標(biāo)記-清除算法一樣會(huì)移除抽活,但是它會(huì)將所有存活的對(duì)象向左移動(dòng)并更新指針 因?yàn)橐苿?dòng)對(duì)象并更新指針 所以成本更高锰什,但是解決了內(nèi)存碎片的問題

clipboard.png


總結(jié)
這三種算法是根據(jù)實(shí)際情況在虛擬機(jī)中結(jié)合使用的梭姓。并不知道單一使用
根據(jù)不同的優(yōu)缺點(diǎn)與場(chǎng)景JVM會(huì)通過運(yùn)算來決定使用哪種嫩码。

3.3 觸發(fā)回收
clipboard.png

手動(dòng)調(diào)用虛擬機(jī)也不會(huì)馬上執(zhí)行铸题,它也是會(huì)等到合適的時(shí)機(jī)進(jìn)行內(nèi)存回收丢间。但是調(diào)用System.gc()會(huì)增到虛擬機(jī)的壓力。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诀艰,一起剝皮案震驚了整個(gè)濱河市其垄,隨后出現(xiàn)的幾起案子绿满,更是在濱河造成了極大的恐慌虽风,老刑警劉巖辜膝,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厂抖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡谭溉,警方通過查閱死者的電腦和手機(jī)橡卤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門碧库,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嵌灰,“玉大人,你說我怎么就攤上這事迁匠【岳#” “怎么了豌鹤?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵傍药,是天一觀的道長拐辽。 經(jīng)常有香客問我俱诸,道長赊舶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任园骆,我火速辦了婚禮锌唾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘滋捶。我一直安慰自己重窟,他們只是感情好惧财,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著霎迫,像睡著了一般知给。 火紅的嫁衣襯著肌膚如雪描姚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天筒扒,我揣著相機(jī)與錄音花墩,去河邊找鬼仲锄。 笑死评汰,一個(gè)胖子當(dāng)著我的面吹牛祠肥,可吹牛的內(nèi)容都是我干的仇箱。 我是一名探鬼主播东羹,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼渊额!你這毒婦竟也來了旬迹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤屹耐,失蹤者是張志新(化名)和其女友劉穎惶岭,沒想到半個(gè)月后犯眠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年量蕊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了残炮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泉瞻,死狀恐怖瓦灶,靈堂內(nèi)的尸體忽然破棺而出抱完,到底是詐尸還是另有隱情巧娱,我是刑警寧澤烘贴,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布桨踪,位于F島的核電站,受9級(jí)特大地震影響铺峭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜傀履,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一莉炉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梆暮,春花似錦绍昂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喘批。三九已至饶深,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間台猴,已是汗流浹背俱两。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國打工宪彩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尿孔,地道東北人筹麸。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓物赶,卻偏偏與公主長得像块差,于是被迫代替她去往敵國和親倔丈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

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