內(nèi)存分配與回收策略
本次讀書筆記主要研究新生代Minor GC在幾種垃圾收集器中的運(yùn)行鹃唯。第一次看Java相關(guān)的書榆芦,第一次在網(wǎng)上寫讀書筆記达椰,給自己記錄一下( ?? ω ?? )y友绝。大部分都是書上的原話,總結(jié)加自己實(shí)現(xiàn)對(duì)比一下而已芋绸。
public class MinorGC {
private static final int _1MB = 1024*1024;
/**
* VM參數(shù): -verbose:gc -Xms20M -Xmx20M -Xmn10M
* -XX:+PrintGCDetails -XX:SurvivorRatio=8
*/
public static void main(String[] args) {
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];
}
}
Serial收集器
該收集器是一個(gè)單線程收集器媒殉,垃圾收集時(shí)必須暫停其他所有工作線程——Stop The World。
優(yōu)點(diǎn):無線程交互開銷摔敛,簡(jiǎn)單高效廷蓉。
缺點(diǎn):暫停響應(yīng)。
書上運(yùn)行上述代碼的結(jié)果是:
GC前马昙,allocation1-3分配到新生代Eden區(qū)桃犬,占用6M刹悴,剩余的2MEden空間不夠分配allocation4,產(chǎn)生Minor GC攒暇。
GC時(shí)土匀,3個(gè)2M的對(duì)象allocation1-3不能放入1M的Survivor空間,于是轉(zhuǎn)移到老年代形用。
GC后就轧,allocation4順利分配到Eden區(qū)。
在本地運(yùn)行以上代碼田度,java -version為:
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal- root_2016_09_18_14_57- b00)
OpenJDK 64-Bit Server VM (build 24.0-b56, mixed mode)
結(jié)果與書上相似:
用java -version為以下配置運(yùn)行:
java version "1.7.0_111"
OpenJDK Runtime Environment (rhel-2.6.7.2.el7_2-x86_64 u111-b01)
OpenJDK 64-Bit Server VM (build 24.111-b01, mixed mode)
運(yùn)行結(jié)果與上述一致钓丰。
Parallel Scavenge收集器
該收集器是一個(gè)新生代收集器,使用復(fù)制算法每币,并行多線程,吞吐量?jī)?yōu)先琢歇。
吞吐量 = 運(yùn)行用戶代碼時(shí)間 / (運(yùn)行用戶代碼時(shí)間 + 垃圾收集時(shí)間)
參數(shù):
- -XX:MaxGCPauseMills 控制最大垃圾收集停頓時(shí)間
- -XX:GCTimeRatio 直接設(shè)置吞吐量大小
調(diào)小新生代大小 —> 垃圾收集頻繁 —> 縮短最大GC停頓時(shí)間 —> 增大了總的垃圾收集時(shí)間(收集次數(shù)*每次停頓時(shí)間)—> 降低吞吐量
當(dāng)使用用java -version為1.7.0_79兰怠,且參數(shù)設(shè)置與上述一致時(shí),運(yùn)行結(jié)果為:
發(fā)現(xiàn)不發(fā)生Minor GC李茫,并且新生代/老年代/永久代的名字變?yōu)镻SYoungGen/ParOldGen/PSPermGen揭保,認(rèn)為是默認(rèn)使用Parallel Scavenge收集器。
由于該收集器優(yōu)先考慮吞吐量魄宏,有GC自適應(yīng)調(diào)節(jié)策略來根據(jù)當(dāng)前系統(tǒng)的運(yùn)行情況動(dòng)態(tài)調(diào)整新生代大小/Eden與Survivor區(qū)的比例/晉升老年代對(duì)象年齡等細(xì)節(jié)參數(shù)秸侣,通過-XX: +UseAdaptiveSizePolicy打開和關(guān)閉以上策略。
當(dāng)沒有打開這個(gè)參數(shù)時(shí)宠互,結(jié)果如上圖所示味榛,allocation1-3占了新生代空間的91%,剩下的空間不足以放下4M的allocation4予跌。
猜想:由于吞吐量?jī)?yōu)先搏色,此時(shí)并不發(fā)生Minor GC,而是直接將allocation4放入老年代券册,減小吞吐量频轿。
當(dāng)打開這個(gè)參數(shù)之后,修改VM參數(shù)如下:
-verbose:gc -XX:+PrintGCDetails -XX:+UseAdaptiveSizePolicy -Xms20M -Xmx20M
運(yùn)行后的結(jié)果為:
疑問1:GC后一個(gè)Survivor區(qū)使用了98%的空間烁焙,504K是放什么的?
疑問2:GC后老年代只放了4176K數(shù)據(jù)航邢,allocation4去哪里了?
G1收集器
運(yùn)作步驟:初始標(biāo)記(標(biāo)記GC Roots能直接關(guān)聯(lián)到的對(duì)象骄蝇,停頓線程膳殷,耗時(shí)短) —> 并發(fā)標(biāo)記(可達(dá)性分析,與用戶程序并發(fā)乞榨,耗時(shí)長(zhǎng)) —> 最終標(biāo)記(修正變動(dòng)秽之,停頓線程当娱,可并行) —> 篩選回收(制定回收計(jì)劃,停頓線程)
分代收集:沒有永久代(待完善)考榨;
空間整合:整體:標(biāo)記—整理跨细,局部(Region間):復(fù)制;
可預(yù)測(cè)停頓河质。
大小相等的獨(dú)立區(qū)域Region集合組成新生代和老年代冀惭,期間無物理隔離。優(yōu)先回收價(jià)值最大的Region掀鹅,提高收集效率散休。
使用如下參數(shù):
-verbose:gc -XX:+UseG1GC -XX:+PrintHeapAtGC -Xms20M -Xmx20M
則運(yùn)行結(jié)果為:
今天先寫到這里。做實(shí)驗(yàn)室的工作去了(乐尊。^▽^)
戚丸。。晚上要看《齊木楠雄的災(zāi)難》扔嵌。
參考:
- 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐》 周志明
- 《G1 垃圾收集器入門 》http://blog.csdn.net/zhanggang807/article/details/45956325