一噩凹、對(duì)象在Eden區(qū)分配
? ? ? ? 驗(yàn)證:對(duì)象優(yōu)先在Eden區(qū)分配愕贡,當(dāng)Eden區(qū)沒有足夠空間時(shí)宽档,會(huì)引發(fā)一次Minor GC
? ? ? ? VM Options:-verbose:gc?-Xms20M -Xmx20M -Xmn5M? -XX: +PrintGCDetails -XX: SurvivorRatio=8
參數(shù)說明:
-verbose:gc? 在控制臺(tái)輸出GC情況
?-XX: +PrintGCDetails????在垃圾回收時(shí)打印詳細(xì)內(nèi)存日志
-Xms10M????最小堆內(nèi)存20M
-Xmx10M????最大堆內(nèi)存20M
-Xmn5M? ? 年輕代5M
-XX: SurvivorRatio=8? ? Eden與Survivor比例為8:1:1
? ? ? ? 運(yùn)行代碼:
? ? ? ? 運(yùn)行結(jié)果:
? ? ? ? 從運(yùn)行結(jié)果可以看出图谷,allocation3在分配空間時(shí)引發(fā)了一次Minor GC票渠,從GC日志當(dāng)中可以看出 :
? ? ? ? (1)GC 產(chǎn)生的原因?yàn)锳llocation Failure逐哈,即年輕代中沒有足夠的空間能夠存儲(chǔ)新的數(shù)據(jù)芬迄;
? ? ? ? (2)垃圾回收器采用的是Parallel Scavenge收集器问顷,PSYoungGen表示新生代,這個(gè)名稱由垃圾回收器決定的禀梳。
? ? ? ? (3)[PSYoungGen: 3809K->488K(4608K)]表示:GC前新生代內(nèi)存區(qū)域已使用3809K杜窄,GC后該內(nèi)存區(qū)域已使用488K,內(nèi)存區(qū)域總?cè)萘繛?608K算途。
? ? ? ? (4)5857K->4828K(19968K), 0.0009839 secs表示:GC前Java堆已使用5857K塞耕,GC后Java堆已使用4828K,Java堆總?cè)萘繛?9968K嘴瓤,本次新生代回收時(shí)間0.0009839 secs扫外。
? ? ? ? (5)PSYoungGen total 4608K, used 2702K 表示:新生代總空間4608K莉钙,已使用2702K ,其中Eden空間4096K筛谚,已使用54%磁玉,F(xiàn)rom Survivor空間總共512K,已使用95%驾讲,To Survivor空間共計(jì)512K蚊伞,已使用0%;
? ? ? ? (6)ParOldGen total 15360K, used 4340K表示:老年代共計(jì)15360K吮铭,已使用4340K时迫;
? ? ? ? (7)Metaspace used 3267K, capacity 4496K, committed 4864K, reserved 1056768K 表示:元空間已加載的類的空間量3267K,分配塊的元數(shù)據(jù)空間大小4496K谓晌,空間塊大小4864K掠拳,元數(shù)據(jù)的空間保留量為1056768K 。
? ? ? ? 分析:
? ? ? ? 由GC日志結(jié)果可以看出扎谎,allocation1和allocation2共計(jì)占用了Eden空間的4096K蜕该,當(dāng)allocation3開始創(chuàng)建時(shí),發(fā)現(xiàn)Eden沒有足夠的存儲(chǔ)空間而引發(fā)了一次Minor GC督暂,垃圾收集器在進(jìn)行垃圾回收時(shí)蛮位,發(fā)現(xiàn)已有的2個(gè)2M大小的對(duì)象,無法全部放入到Survivor空間预吆,所以只好放入老年代中龙填,老年代已使用的4M正對(duì)應(yīng)allocation1和allocation2,GC后1M的allocation3和1M的allocation4順利的分配到了Eden空間上拐叉,占據(jù)一半的Eden空間岩遗。
二、大對(duì)象直接進(jìn)入老年代
????????驗(yàn)證:大對(duì)象直接進(jìn)入老年代
????????VM Options:-verbose:gc?-Xms20M -Xmx20M -Xmn5M? -XX: +PrintGCDetails -XX: SurvivorRatio=8
參數(shù)說明:
-verbose:gc? 在控制臺(tái)輸出GC情況?
-XX: +PrintGCDetails????在垃圾回收時(shí)打印詳細(xì)內(nèi)存日志
-Xms10M????最小堆內(nèi)存20M
-Xmx10M????最大堆內(nèi)存20M
-Xmn5M? ? 年輕代5M
-XX: SurvivorRatio=8? ? Eden與Survivor比例為8:1:1
? ? ? ? 運(yùn)行代碼:
? ? ? ? 運(yùn)行結(jié)果:
? ? ? ? 分析:
? ? ? ? 由運(yùn)行結(jié)果日志可以看出凤瘦,局部變量_1MB在新生代上分配宿礁,當(dāng)8M的大對(duì)象allocation1進(jìn)入,因在新生代無法找到足夠的內(nèi)存空間蔬芥,被直接分配在了老年代梆靖,ParOldGen used 8192K 正好是allocation1使用的8M。
三笔诵、長(zhǎng)期存活的對(duì)象進(jìn)入老年代
? ? ? ? 驗(yàn)證:長(zhǎng)期存活的對(duì)象進(jìn)入老年代
? ??????VM Options:-verbose:gc?-Xms20M -Xmx20M -Xmn5M? -XX:MaxTenuringThreshold=1 -XX: +PrintGCDetails -XX: SurvivorRatio=8?
參數(shù)說明:
-verbose:gc? 在控制臺(tái)輸出GC情況?
-XX: +PrintGCDetails????在垃圾回收時(shí)打印詳細(xì)內(nèi)存日志
-Xms10M????最小堆內(nèi)存20M
-Xmx10M????最大堆內(nèi)存20M
-Xmn5M? ? 年輕代5M
-XX: SurvivorRatio=8? ? Eden與Survivor比例為8:1:1
-XX:MaxTenuringThreshold=1 對(duì)象晉升老年代的年齡閾值為1
? ? ? ? 運(yùn)行代碼:
????????? ??????????
? ? ? ? 運(yùn)行結(jié)果:
? ? ? ? 運(yùn)行結(jié)果:
? ? ? ? 分析:
? ? ? ? 從前面章節(jié)了解到對(duì)象會(huì)先進(jìn)入Eden空間返吻,從圖 3-2?運(yùn)行結(jié)果可以看出allocation1在新生代分配,allocation2大對(duì)象直接進(jìn)入老年代乎婿;
? ? ? ? 圖 3-4 運(yùn)行結(jié)果看出allocation3創(chuàng)建時(shí)引發(fā)了一次Minor GC测僵,因-XX:MaxTenuringThreshold=1的緣故,經(jīng)歷了一次GC谢翎,allocation1的分代年齡加一捍靠,晉升到老年代沐旨,與allocation2共占據(jù)5M空間。
四榨婆、 動(dòng)態(tài)對(duì)象年齡判定
? ? ? ? HotSpot虛擬機(jī)并不是必須要對(duì)象的年齡達(dá)到XX:MaxTenuringThreshold 指定的閾值才能晉升老年代希俩,如果Survivor空間中,相同年齡的所有對(duì)象大小的總和大于Survivor空間的一半纲辽,年齡大于或等于該年齡的對(duì)象就可以直接進(jìn)入老年代颜武,無需等到XX:MaxTenuringThreshold 指定的年齡。
? ? ? ???VM Options:-verbose:gc?-Xms20M -Xmx20M -Xmn5M?-XX:MaxTenuringThreshold=2?-XX: +PrintGCDetails -XX: SurvivorRatio=8?
參數(shù)說明:
-verbose:gc? 在控制臺(tái)輸出GC情況?
-XX: +PrintGCDetails????在垃圾回收時(shí)打印詳細(xì)內(nèi)存日志
-Xms10M????最小堆內(nèi)存20M
-Xmx10M????最大堆內(nèi)存20M
-Xmn4M? ? 年輕代4M
-XX: SurvivorRatio=8? ? Eden與Survivor比例為8:1:1
-XX:MaxTenuringThreshold=2 對(duì)象晉升老年代的年齡閾值為2
? ? ? ? 運(yùn)行代碼:
? ? ? ? 運(yùn)行結(jié)果:
? ? ? ? 分析:
? ? ? ? 只經(jīng)歷了一次GC拖吼,allocation1和allocation2的GC分代年齡為1鳞上,沒有達(dá)到XX:MaxTenuringThreshold 指定的年齡。而allocation1和allocation2占用的空間大于Survivor空間的一半吊档,直接進(jìn)入老年代篙议。
五、空間分配擔(dān)保
? ? ? ? 在Minor GC發(fā)生前怠硼,Java虛擬機(jī)必須檢查老年代最大可用的連續(xù)空間是否大于新生代所有對(duì)象的總空間鬼贱,如果成立,則本次Minor GC是安全的香璃;否則这难,虛擬機(jī)會(huì)查看-XX:HandlerPromotionFailure參數(shù)的設(shè)置值是否允許擔(dān)保失敗:如果允許擔(dān)保失敗,虛擬機(jī)將會(huì)繼續(xù)檢查老年代最大可用的連續(xù)空間是否大于歷次晉升到老年代對(duì)象的平均大小葡秒,如果大于姻乓,將進(jìn)行一次Minor GC;如果小于眯牧,或者?-XX:HandlerPromotionFailure 為false蹋岩,則不會(huì)進(jìn)行Minor GC,改為進(jìn)行一次Full GC学少。
? ? ? ? 新生代采用復(fù)制算法剪个,其中一個(gè)Survivor空間始終作為輪換備份空間,假設(shè)最極端的情況版确,GC后扣囊,新生代的所有對(duì)象依然存活,那么就需要老年代進(jìn)行分配擔(dān)保阀坏,把Survivor無法容納的對(duì)象送入老年代如暖。老年代擔(dān)保的前提是本身還有空間能容納這些對(duì)象笆檀,但老年代不知道本次回收后會(huì)有多少存活對(duì)象忌堂,因此只能對(duì)之前每一次晉升到老年代的對(duì)象取平均值,并與老年代剩余空間做比較酗洒,從而決定是否觸發(fā)Full GC來騰出更多的空間士修。
? ? ? ? 這種擔(dān)保的做法存在風(fēng)險(xiǎn)枷遂,假如本次Minor GC后存活的對(duì)象突增,依然會(huì)存在擔(dān)保失敗的情況棋嘲,而不得不造成更長(zhǎng)停頓時(shí)間的Full GC酒唉。