JVM源碼分析之Java對象的內(nèi)存分配

簡書 占小狼
轉(zhuǎn)載請注明原創(chuàng)出處栽烂,謝謝!

看得越多焰手,懂的越少怀喉,還年輕躬拢,多學(xué)習见间!

接著上篇《JVM源碼分析之Java對象的創(chuàng)建過程》工猜,本文對Java對象的內(nèi)存分配過程進行深入分析篷帅,其中有以下幾種分配方式:
1、從線程的局部緩沖區(qū)分配臨時內(nèi)存
2惊橱、從內(nèi)存堆中分配臨時內(nèi)存
3李皇、從內(nèi)存堆中分配永久內(nèi)存

新建一個對象時宙枷,由對應(yīng)的instanceKlass對象計算出需要多大的內(nèi)存,并調(diào)用CollectedHeapcommon_mem_allocate_noinit方法分配指定大小的內(nèi)存卓囚,實現(xiàn)如下:

從線程的局部緩沖區(qū)分配臨時內(nèi)存

TLAB技術(shù)是每個線程在Java堆中預(yù)先分配了一小塊內(nèi)存哪亿,當有對象創(chuàng)建請求內(nèi)存分配時贤笆,就會在該塊內(nèi)存上進行分配芥永,而不需要在Java堆通過同步控制進行內(nèi)存分配。如果UseTLAB為真板辽,則使用TLAB技術(shù)(Thread-Local Allocation Buffers)棘催,將分配工作交由線程自行完成醇坝,實現(xiàn)如下:

1、如果線程的局部緩沖區(qū)可以分配指定大小的內(nèi)存画畅,則直接分配夜赵;
2、否則執(zhí)行allocate_from_tlab_slow在Java堆上進行分配摊腋,實現(xiàn)如下:

3兴蒸、通過allocate_new_tlab從Java堆上重新為線程分配一塊局部緩沖區(qū)细办,實現(xiàn)如下:

其中mem_allocate方法實現(xiàn)從Java堆分配臨時內(nèi)存。

從內(nèi)存堆中分配臨時內(nèi)存

在內(nèi)存堆管理器看來岛啸,為普通對象分配內(nèi)存和為某一線程分配一塊本地分配緩沖區(qū)在本質(zhì)上都是一樣的茴肥,這塊內(nèi)存都是臨時的,只能從新生代或老年代中進行分配瞬铸,通過gc策略GenCollectorPolicy::mem_allocate_work方法進行實現(xiàn)嗓节,大概步驟如下:

step 1

1皆警、gch->no_gc_in_progress()確保當前JVM沒有正在進行g(shù)c耀怜;
2、參數(shù)gc_overhead_limit_was_exceeded表示當前內(nèi)存分配操作是否發(fā)生了gc,以及gc耗時是否超過設(shè)置限制从诲,主要針對一些對延遲敏感的場景,當該參數(shù)為true時略步,拋出OOM的異常給上層定页;

step 2

通過重試機制確保內(nèi)存能夠分配成功:
1典徊、首先在新生代采用無鎖的方式嘗試分配內(nèi)存,通過Atomic::cmpxchg_ptr的CAS操作對新生代空閑內(nèi)存進行同步分配羡铲,最終實現(xiàn)如下:

2也切、如果分配失敗腰湾,則執(zhí)行step 3费坊;

step 3

1、如果在新生代中內(nèi)存分配失敗导犹,則通過加鎖方式進行分配谎痢;
2卷雕、參數(shù)first_only表示當前是否只應(yīng)該在新生代分配內(nèi)存,如果新生代的剩余空間不夠滨嘱,則嘗試在老年代進行分配太雨;
3魁蒜、依次嘗試從內(nèi)存各個代中分配內(nèi)存吩翻,實現(xiàn)如下:

4狭瞎、如果內(nèi)存分配成功搏予,則返回,否則執(zhí)行step 4碗殷;

step 4

1亿扁、gc_locker::is_active_and_needs_gc()為真時鸟廓,表示當前其它線程已經(jīng)觸發(fā)了gc引谜;
2、如果is_tlab為真毒涧,表示當前線程正在為局部分配緩沖區(qū)申請內(nèi)存贝室;
3、如果!gch->is_maximal_no_gc()為真滑频,表示新生代或老年代可以進行內(nèi)存擴展峡迷,擴展完成后银伟,再次嘗試從各代中進行分配,實現(xiàn)如下:

4绘搞、如果內(nèi)存擴展之后還是沒有足夠的內(nèi)存滿足分配需求彤避,則執(zhí)行step 5;

step 5

如果當前線程沒有位于jni的臨界區(qū)夯辖,將釋放Java堆的互斥鎖琉预,以使得請求gc的線程可以進行g(shù)c操作,等所有本地線程退出臨界區(qū)和gc完成后蒿褂,將繼續(xù)循環(huán)嘗試分配內(nèi)存模孩。

step 6

1尖阔、如果各代無法分配對象的內(nèi)存榨咐,說明需要觸發(fā)一次gc操作,提交VM一個GenCollectForAllocation操作谴供,最終由名為VM Thread的JVM級線程調(diào)度執(zhí)行块茁;
2、當操作執(zhí)行成功并返回時桂肌,如果gc鎖已被加鎖数焊,說明已經(jīng)由其它線程觸發(fā)了gc,則繼續(xù)循環(huán)以等待gc完成崎场;
3佩耳、否則當前線程等待gc完成,判斷gc耗時是否超過設(shè)置的gc超時上限谭跨,并執(zhí)行軟引用的清除干厚;
4、如果gc超時螃宙,則給上層調(diào)用返回NULL蛮瞄,讓其拋出內(nèi)存溢出錯誤;


我是占小狼
坐標魔都谆扎,白天上班族挂捅,晚上是知識的分享者
如果讀完覺得有收獲的話,歡迎點贊加關(guān)注

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末堂湖,一起剝皮案震驚了整個濱河市闲先,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌无蜂,老刑警劉巖伺糠,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異酱讶,居然都是意外死亡退盯,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門泻肯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渊迁,“玉大人,你說我怎么就攤上這事灶挟×鹦啵” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵稚铣,是天一觀的道長箱叁。 經(jīng)常有香客問我墅垮,道長,這世上最難降的妖魔是什么耕漱? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任算色,我火速辦了婚禮,結(jié)果婚禮上螟够,老公的妹妹穿的比我還像新娘灾梦。我一直安慰自己,他們只是感情好妓笙,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布若河。 她就那樣靜靜地躺著,像睡著了一般寞宫。 火紅的嫁衣襯著肌膚如雪萧福。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天辈赋,我揣著相機與錄音鲫忍,去河邊找鬼。 笑死炭庙,一個胖子當著我的面吹牛饲窿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播焕蹄,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼逾雄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了腻脏?” 一聲冷哼從身側(cè)響起鸦泳,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎永品,沒想到半個月后做鹰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡鼎姐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年钾麸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炕桨。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡饭尝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出献宫,到底是詐尸還是另有隱情钥平,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布姊途,位于F島的核電站涉瘾,受9級特大地震影響知态,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜立叛,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一负敏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧囚巴,春花似錦原在、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽村怪。三九已至秽浇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間甚负,已是汗流浹背柬焕。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留梭域,地道東北人斑举。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像病涨,于是被迫代替她去往敵國和親富玷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

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