深入理解java虛擬機(jī)(第二版)——第三章:內(nèi)存分配與回收策略

一简僧、java對(duì)象分配策略

java中所說(shuō)的自動(dòng)內(nèi)存管理最終可以歸結(jié)到兩個(gè)問(wèn)題:

  • 自動(dòng)分配不存
  • 自動(dòng)回收內(nèi)存
    對(duì)象的內(nèi)存分配主要是在堆上進(jìn)行牍帚,堆根據(jù)對(duì)象不同的存活周期分為不同的區(qū)域塞蹭,新生對(duì)象一般分在了Eden區(qū)域蕴掏,如果啟動(dòng)了線程分配緩沖,則優(yōu)先會(huì)分配到TLAB上伴奥。有少數(shù)情況新生對(duì)象會(huì)直接分配到老年代區(qū)域。實(shí)際情況要根據(jù)虛擬機(jī)模式和收集器組合來(lái)確定咕幻。
    以下結(jié)論是Client模式下配合Serial和Serial Old收集器渔伯。

1、對(duì)象優(yōu)先分配在Eden區(qū)域

在多數(shù)情況下肄程,對(duì)象優(yōu)先分配在Eden區(qū)域锣吼,當(dāng)Eden區(qū)域的沒(méi)有足夠的內(nèi)存分配時(shí),虛擬機(jī)將發(fā)生一次minor GC蓝厌。
以下代碼測(cè)試新生對(duì)象的分配機(jī)制玄叠。設(shè)置堆大小為20M,不可擴(kuò)展拓提,新生代大小為10M读恃,老年代10M,Eden和from survivor和to survivor的比例為8:1:1代态。

public class TestAllocation {
    private static final int _1MB = 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];
    }
    public static void main(String[] args) {
        testAllocation();
    }
}

在進(jìn)行allocation1 寺惫,allocation12, allocation13時(shí)對(duì)象正常分配到Eden區(qū)蹦疑,在分配第四個(gè)對(duì)象的時(shí)候發(fā)現(xiàn)Eden的空間不夠用西雀,觸發(fā)一次Minor GC,minor GC過(guò)后對(duì)象1,2,3正常情況下應(yīng)該被復(fù)制算法復(fù)制到另一塊survivor空間歉摧,但是由于survivor空間不夠所以通過(guò)分配擔(dān)保將123轉(zhuǎn)移到了老年代空間中艇肴,此時(shí)Eden和兩塊survivor空閑腔呜,老年代空間占用6MB。最后第四個(gè)對(duì)象成功分配到Eden空間再悼。
(在java8中運(yùn)行上述代碼核畴,沒(méi)有出現(xiàn)相同的結(jié)果。冲九。谤草。。莺奸。)

2咖刃、大對(duì)象直接進(jìn)入老年代

大對(duì)象的存儲(chǔ)需要大量的連續(xù)的內(nèi)存空間,這對(duì)虛擬機(jī)的內(nèi)存管理來(lái)說(shuō)不是一個(gè)好消息憾筏。虛擬機(jī)設(shè)置了-XX:PretenureSizeThreshold做標(biāo)志嚎杨,當(dāng)新生對(duì)象大小超過(guò)了-XX:PretenureSizeThreshold設(shè)置的大小則獨(dú)享直接分配在老年代中。這樣做的好處是避免了在新生代中大量的復(fù)制(新生代采用的是復(fù)制算法)氧腰。壞處是增加了老年代的垃圾收集任務(wù)枫浙。且老年代的垃圾收集速度要比新生代耗時(shí)長(zhǎng)很多。

3古拴、長(zhǎng)期存活的對(duì)象進(jìn)入老年代

虛擬機(jī)為每一個(gè)對(duì)象定義了一個(gè)對(duì)象年齡計(jì)數(shù)器箩帚,如果在出生在Eden經(jīng)過(guò)一個(gè)Minor GC后存活且被survivor容納,則age設(shè)為1黄痪。對(duì)象在survivor每熬過(guò)一次Minor GC則age加1紧帕,當(dāng)age增加到15時(shí)晉升到老年代中。晉升age可以調(diào)節(jié)桅打,參數(shù)為-XX:MaxTenuringThreshold是嗜。
  虛擬機(jī)并不是永遠(yuǎn)要求對(duì)象的年齡達(dá)到-XX:MaxTenuringThreshold之后才能晉升到老年代。如果在Survivor空間的相同年齡所有對(duì)象大小的總和超過(guò)了Survivor空間的一半挺尾,則虛擬機(jī)就允許大于或等于該年齡的對(duì)象直接進(jìn)入老年代鹅搪。

二、 其他概念總結(jié)

1遭铺、GC分類

GC按照發(fā)生位置分為Minor GC和Major GC:

  • Minor GC:發(fā)生在新生代丽柿。由于新生代對(duì)象的特點(diǎn),Minor GC發(fā)生較頻繁魂挂,速度也很快甫题。
  • Major GC/Full GC:發(fā)生在老年代。Major GC一般會(huì)伴隨多次的Minor GC涂召,速度也較Minor GC慢出一個(gè)數(shù)量級(jí)坠非。

2、空間分配擔(dān)保

在新生代中使用的收集算法是復(fù)制算法芹扭,一般將新生代分成三個(gè)區(qū)域麻顶,Eden區(qū),from Survivor和to Survivor舱卡,這三個(gè)區(qū)域的比大小例是8:1:1辅肾。一半新生對(duì)象沒(méi)有特殊設(shè)置的話會(huì)直接出生在Eden區(qū)域,如果Eden區(qū)域空間不夠則會(huì)發(fā)生一次Minor GC轮锥。如果在Minor GC時(shí)Survivor空間不夠這就需要分配擔(dān)保矫钓。
分配擔(dān)保就是Minor GC過(guò)程中Survivor區(qū)域不足以容納Eden區(qū)的存活對(duì)象從而向老年代借一塊區(qū)域用于存放存活對(duì)象。
老年代在執(zhí)行分配擔(dān)保時(shí)會(huì)有一些執(zhí)行機(jī)制舍杜。
1新娜、在Minor GC前虛擬機(jī)會(huì)檢查老年代的最大可用連續(xù)空間是否大于新生代所有對(duì)象總空間,如果大于既绩,則分配擔(dān)保安全概龄。
2、如果老年代最大連續(xù)總空間小于新生代所有對(duì)象之和饲握。虛擬機(jī)檢查HandlePromotionFailure設(shè)置是否允許分配擔(dān)保失敗私杜,如果允許。繼續(xù)檢查老年代最大連續(xù)空間是否大于歷次晉升到老年代對(duì)象的平均大小救欧。如果大于衰粹,虛擬機(jī)將允許發(fā)生Minor GC,如果小于笆怠,HandlePromotionFailure設(shè)置為不允許铝耻,此時(shí)需要進(jìn)行一次Full GC。
(JDK 6 Update 24之后的規(guī)則變?yōu)橹灰夏甏倪B續(xù)空間大于新生代對(duì)象總大小或者歷次晉升的平均大小就會(huì)進(jìn)行Minor GC蹬刷,否則將進(jìn)行Full GC瓢捉。)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市办成,隨后出現(xiàn)的幾起案子泊柬,更是在濱河造成了極大的恐慌,老刑警劉巖诈火,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兽赁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡冷守,警方通過(guò)查閱死者的電腦和手機(jī)刀崖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拍摇,“玉大人亮钦,你說(shuō)我怎么就攤上這事〕浠睿” “怎么了蜂莉?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵蜡娶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我映穗,道長(zhǎng)窖张,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任蚁滋,我火速辦了婚禮宿接,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辕录。我一直安慰自己睦霎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布走诞。 她就那樣靜靜地躺著副女,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚣旱。 梳的紋絲不亂的頭發(fā)上肮塞,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音姻锁,去河邊找鬼枕赵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛位隶,可吹牛的內(nèi)容都是我干的拷窜。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼涧黄,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼篮昧!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起笋妥,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤懊昨,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后春宣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酵颁,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年月帝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了躏惋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嚷辅,死狀恐怖簿姨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤扁位,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布准潭,位于F島的核電站,受9級(jí)特大地震影響域仇,放射性物質(zhì)發(fā)生泄漏刑然。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一殉簸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沽讹,春花似錦般卑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至挚瘟,卻和暖如春叹谁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背乘盖。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工焰檩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人订框。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓析苫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親穿扳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子衩侥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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