【第六篇】深入學(xué)習(xí)Java虛擬機(jī)之內(nèi)存分配與回收策略

說明:是在Serial/Serial Old收集器下的內(nèi)存分配和回收策略

兩個(gè)概念

Minor GC:指發(fā)生在新生代的垃圾收集動作伐谈,因?yàn)镴ava對象大多都具備朝生夕死的特性铺董,所以Minor GC非常頻繁榔幸,一般回收速度也比較快奏路。
Full GC: 指發(fā)生在老年代的GC爱榕,出現(xiàn)了Major GC阵幸。Major GC的速度一般會比Minor GC 慢10倍以上

內(nèi)存的分配策略

1. 優(yōu)先在Eden上分配

大多數(shù)情況下花履,對象在新生代Eden上分配。當(dāng)Eden區(qū)沒有足夠空間進(jìn)行分配時(shí)挚赊,虛擬機(jī)將發(fā)起一起Minor GC诡壁。

我們可以看一個(gè)例子:

設(shè)置參數(shù):
-XX:+PrintGCDetails:收集器日志參數(shù)
-Xms20m:堆初始分配大小
-Xmx20m:堆最大可擴(kuò)展內(nèi)存空間,同-Xms值想同荠割,則意味著堆不可擴(kuò)展
-Xmn10m:新生代分配10M

剩下10M分配給老年代妹卿。

-XX:SurvivorRatio=8設(shè)定新生代中Eden區(qū)與Survivor區(qū)的空間占比是8:1,即Eden區(qū)域?yàn)?M蔑鹦。

private static final int _1MB = 1024 * 1024;
/**
* VM 參數(shù):-verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
* -XX:SurvivorRatio=8
*/
public static void testAllocation() {
  byte[] allocation1,allocation2,allocation3,allocation4;
  allocation1 = new byte[2 * _1MB];
  allocation2 = new byte[2 * _1MB];
  allocation3 = new byte[2 * _1MB];
  allocation4 = new byte[4 * _1MB]; // 出現(xiàn)一次Minor GC
}

運(yùn)行結(jié)果如下圖所示:

運(yùn)行結(jié)果

說明:
在為allocation4對象分配內(nèi)存空間時(shí)夺克,會發(fā)生一次Minor GC,GC的結(jié)果是新生代6651KB變?yōu)?48KB嚎朽,而總內(nèi)存占用量則幾乎沒有減少铺纽,因?yàn)閍llocation1、allocation2哟忍、allocation3三個(gè)對象都是存活的狡门,虛擬機(jī)幾乎沒有找到可回收的對象)

這次GC發(fā)生的原因是因?yàn)榻oallocation4分配內(nèi)存的時(shí)候,Eden已經(jīng)被占用了6MB锅很,剩下的空間不足以分配allocation4對象需要的4MB空間其馏,因此發(fā)生MinorGC。

但是粗蔚,GC期間發(fā)現(xiàn)3個(gè)2MB的對象全部無法放入Survivor空間尝偎,因?yàn)镾urvivor空間只有1MB大小,所以只能通過分配擔(dān)保機(jī)制鹏控,將Eden空間里分配的allocation1致扯、allocation2、allocation3對象轉(zhuǎn)移到老年代中当辐。

這次GC結(jié)束后抖僵,4MB的allocation4對象順利分配在Eden中,因此程序最后執(zhí)行完的結(jié)果是Eden占用4MB(被allocation4占用)缘揪,Survivor空閑耍群,老年代被占用6MB(被轉(zhuǎn)移來的allocation1义桂、allocation2、allocation3對象占用)

2. 大對象直接進(jìn)入老生代

所謂的大對象是指蹈垢,需要大量連續(xù)內(nèi)存空間的Java對象慷吊,最經(jīng)典的大對象就是那種很長的字符串以及數(shù)組。例如曹抬,下面例子中的byte[]數(shù)組就是典型的大對象溉瓶。

參數(shù):-XX:PretenureSizeThreshold(該設(shè)置只對Serial和ParNew收集器生效) 可以設(shè)置進(jìn)入老生代的大小限制,我們設(shè)置為3M谤民,則大于3M的大對象就直接進(jìn)入老年代

private static final int _1MB = 1024 * 1024;
/**
* VM 參數(shù):-verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
* -XX:SurvivorRatio=8
* -XX:PretenureSizeThreshold=3145728
*/
public static void testPretenureSizeThreshold() {
  byte[] allocation;
  allocation = new byte[4 * _1MB]; // 直接分配在老年代中
}

3. 長期存活的對象進(jìn)入老年代

如果對象在Eden空間出生并經(jīng)過第一次MinorGC后仍然存活堰酿,并且能被Survivor空間容納的話,將被移動到Survivor空間中张足,并且對象年齡設(shè)為1.

對象在Survivor區(qū)中每“熬過”一次MinorGC触创,年齡增加1歲,當(dāng)它的年齡增加到一定程度为牍,默認(rèn)為15歲哼绑,就會被晉升到老年代中。晉升老年代的年齡閾值吵聪,可以通過參數(shù)-XX:MaxTenuringThreshold設(shè)置凌那。

4. 動態(tài)對象年齡判定

為了使內(nèi)存分配更加靈活,虛擬機(jī)并不要求對象年齡達(dá)到MaxTenuringThreshold才晉升老年代

如果Survivor區(qū)中相同年齡所有對象大小的總和大于Survivor區(qū)空間的一半吟逝,年齡大于或等于該年齡的對象在Minor GC時(shí)將復(fù)制至老年代

5. 空間分配擔(dān)保

新生代使用復(fù)制算法,當(dāng)Minor GC時(shí)如果存活對象過多赦肋,無法完全放入Survivor區(qū)块攒,就會向老年代借用內(nèi)存存放對象,以完成Minor GC佃乘。

在觸發(fā)Minor GC時(shí)囱井,虛擬機(jī)會先檢測之前GC時(shí)租借的老年代內(nèi)存的平均大小是否大于老年代的剩余內(nèi)存,如果大于趣避,則將Minor GC變?yōu)橐淮蜦ull GC庞呕,如果小于,則查看虛擬機(jī)是否允許擔(dān)保失敗程帕,如果允許擔(dān)保失敗住练,則只執(zhí)行一次Minor GC,否則也要將Minor GC變?yōu)橐淮蜦ull GC愁拭。

說白了讲逛,新生代放不下就會借用老年代的空間來進(jìn)行GC

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市岭埠,隨后出現(xiàn)的幾起案子盏混,更是在濱河造成了極大的恐慌蔚鸥,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件许赃,死亡現(xiàn)場離奇詭異止喷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)混聊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門启盛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人技羔,你說我怎么就攤上這事僵闯。” “怎么了藤滥?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵鳖粟,是天一觀的道長。 經(jīng)常有香客問我拙绊,道長向图,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任标沪,我火速辦了婚禮榄攀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘金句。我一直安慰自己檩赢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布违寞。 她就那樣靜靜地躺著贞瞒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪趁曼。 梳的紋絲不亂的頭發(fā)上军浆,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機(jī)與錄音挡闰,去河邊找鬼乒融。 笑死,一個(gè)胖子當(dāng)著我的面吹牛摄悯,可吹牛的內(nèi)容都是我干的赞季。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼射众,長吁一口氣:“原來是場噩夢啊……” “哼碟摆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叨橱,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤典蜕,失蹤者是張志新(化名)和其女友劉穎断盛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體愉舔,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钢猛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了轩缤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片命迈。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖火的,靈堂內(nèi)的尸體忽然破棺而出壶愤,到底是詐尸還是另有隱情,我是刑警寧澤馏鹤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布征椒,位于F島的核電站,受9級特大地震影響湃累,放射性物質(zhì)發(fā)生泄漏勃救。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一治力、第九天 我趴在偏房一處隱蔽的房頂上張望蒙秒。 院中可真熱鬧,春花似錦宵统、人聲如沸晕讲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽益兄。三九已至,卻和暖如春箭券,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疑枯。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工辩块, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荆永。 一個(gè)月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓废亭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親具钥。 傳聞我的和親對象是個(gè)殘疾皇子豆村,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

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