深入理解java虛擬機(jī)(二)--GC與內(nèi)存分配策略

一、判斷對象是否已死

1搜锰、引用計(jì)數(shù)算法

? ? ? 給對象中添加一個引用計(jì)數(shù)器耿战,每當(dāng)有一個地方引用它時剂陡,計(jì)數(shù)器值就加1,當(dāng)引用時效時薯嗤,計(jì)數(shù)器值就減1纤泵;任何時刻計(jì)數(shù)器為0的對象就是不可能再被使用的捏题,引用計(jì)數(shù)算法管理內(nèi)存很高效公荧,但是java虛擬機(jī)沒有使用,因?yàn)槭撬茈y解決對象間相互循環(huán)引用的問題窟社。兩個對象互相引用绪钥,導(dǎo)致它們的引用計(jì)數(shù)都不為0程腹,于是引用計(jì)數(shù)算法無法通知GC收集器回收它們。色鸳、

2命雀、可達(dá)性分析算法

? ? Java是通過可達(dá)性分析(Reachability Analysis)來判定對象是否存活的斩箫。這個算法的基本思路就是通過一系列的稱為“GC Roots” 的對象作為起始點(diǎn)校焦,從這些節(jié)點(diǎn)開始向下搜索,搜索所走過的路徑稱為引用鏈(Reference Chain)氛雪,當(dāng)一個對象到GC Roots沒有任何引用鏈相連時报亩,則證明對象是不可用的井氢。

在Java語言中花竞,可以作為GC Roots的對象包括下面幾種:

? ? 虛擬機(jī)棧(棧幀中的本地變量表)中引用的對象。

? ? 方法區(qū)中靜態(tài)類屬性引用的對象零远。

? ? 方法區(qū)中常量引用的對象牵辣。

? ? 本地方法棧中JNI(即一般說的Native方法)引用的對象纬向。

二、垃圾收集算法

1琢岩、標(biāo)記-清除算法

? ? 最基礎(chǔ)的收集算法是“標(biāo)記-清除”(Mark-Sweep)算法膳帕,算法分為“標(biāo)記”和“清除”兩個階段:首先標(biāo)記出所有需要收回的對象危彩,在標(biāo)記完成之后統(tǒng)一回收所有被標(biāo)記的對象汤徽。它有兩個不足:一個是效率問題,標(biāo)記和清除兩個過程的效率都不高拼坎;另一個是空間問題泰鸡,標(biāo)記清除之后會產(chǎn)生大量的不連續(xù)的內(nèi)存碎片壳鹤,空間碎片太多可能會導(dǎo)致以后在程序運(yùn)行過程中需要分配較大對象時芳誓,無法找到足夠的連續(xù)內(nèi)存從而不得不提前觸發(fā)另一次垃圾收集動作。

2匿值、復(fù)制算法

? ? 為了解決效率問題挟憔,一種稱為“復(fù)制”(Copying)的收集算法出現(xiàn)了绊谭,它將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當(dāng)這塊的內(nèi)存用完了趟大,就將還存活著的對象復(fù)制到另一塊上面铣焊,然后再把已使用過的內(nèi)存空間一次清理掉曲伊。這樣使得每次都是對整個半?yún)^(qū)進(jìn)行內(nèi)存回收,內(nèi)存分配時也就不用考慮內(nèi)存碎片等復(fù)雜情況坟募,只要移動堆頂指針懈糯,按順序分配內(nèi)存即可羡棵,實(shí)現(xiàn)簡單,運(yùn)行高效贿讹。代價很高民褂,將內(nèi)存縮小為原來的一半祖屏。


3袁勺、標(biāo)記-整理算法

? ? “標(biāo)記-整理”(Mark-Compact)算法期丰,標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣,但后續(xù)步驟不是直接對可回收對象進(jìn)行清理街立,而是讓所有存活的對象都向一端移動赎离,然后直接清理掉端邊界以外的內(nèi)存。


4虽画、分代收集算法

? ? “分代收集”(Generational Collection)算法码撰,根據(jù)對象存活周期的不同將內(nèi)存劃分為幾塊脖岛。一般是把Java堆分為新生代和老年代颊亮,這樣既可以根據(jù)各個年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴ū嘈帧T谛律泻菰В看卫占瘯r都發(fā)現(xiàn)有大批對象死去,只有少量存活卸察,那就選用復(fù)制算法铅祸,只需要付出少量對象的復(fù)制成本就可以完成收集坑质。而老年代中因?yàn)閷ο蟠婊盥矢摺]有額外空間對它進(jìn)行分配擔(dān)保临梗,就必須使用“標(biāo)記-清除”或者“標(biāo)記-整理”算法來進(jìn)行回收涡扼。

三、垃圾收集器


1盟庞、Serial收集器

? ? ? 這個收集器時單線程的收集器吃沪,它進(jìn)行來寄收集時,必須暫停其他所有的工作線程什猖,直到它收集結(jié)束票彪。


2、ParNew收集器

? ? ? ParNew收集器是Serial收集器的多線程版本降铸,除了使用多線程進(jìn)行垃圾收集之外在旱,其余行為包括Serial收集器可用的所有控制參數(shù)、收集算法推掸、Stop The World桶蝎、對象分配規(guī)則、回收策略等都與Serial收集器一樣谅畅。


3俊嗽、Parallel Scavenge收集器

? ? ? Parallel Scavenge收集器是一個新生代收集器,它也是使用復(fù)制算法的收集器铃彰,又是并行的多線程收集器。Parallel Scavenge收集器的目標(biāo)是達(dá)到一個可控制的吞吐量(Throughput)芯咧。所謂的吞吐量就是CPU用于運(yùn)行用戶代碼的時間與CPU總消耗時間的比值牙捉,即吞吐量=運(yùn)行用戶代碼時間/(運(yùn)行用戶代碼時間+垃圾收集時間)。

? ? ? Parallel Scavenge收集器提供了兩個參數(shù)用于精確控制吞吐量敬飒,分別是控制最大垃圾收集停頓時間的-XX:MaxGCPauseMillis參數(shù)以及直接設(shè)置吞吐量大小的-XX:GCTimeRatio參數(shù)邪铲。 Parallel Scavenge收集器還有一個參數(shù):-XX:+UseAdaptiveSizePolicy,這個參數(shù)打開之后无拗,就不需要手工指定新生代的小写健(-Xms)、Eden與Survivor區(qū)的比例(-XX:SurvivorRatio)英染、晉升老年代對象大欣咳恰(-XX:PretenureSizeThreshold)等參數(shù)了。虛擬機(jī)會自動調(diào)整四康,這種方式稱為GC自適應(yīng)的調(diào)節(jié)策略(GC Ergonomics)搪搏。

4、Serial Old收集器

? ? ? Serial Old收集器是Serial收集器的老年代版本闪金,是一個單線程收集器疯溺,使用“標(biāo)記-整理”算法。這個收集器的主要意義也是在于給Client模式下的虛擬機(jī)使用哎垦。如果在Server模式下囱嫩,那么它主要還有兩大用途:一種用途是JDK1.5以及之前的版本中與Parallel Scavenge收集器搭配使用,另一種用途是作為CMS收集器的后備預(yù)案漏设,在并發(fā)收集發(fā)生Concurrent Mode Failure時使用墨闲。


5、Parallel Old收集器

? ? ? Parallel Old收集器是Parallel Scavenge收集器的老年代版本愿题,使用多線程和“標(biāo)記-整理”算法损俭。


6蛙奖、CMS收集器

? ? CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標(biāo)的收集器。是基于“標(biāo)記-清楚”算法實(shí)現(xiàn)的杆兵,主要有四個運(yùn)行步驟雁仲,包括:初始標(biāo)記(CMS initial mark),并發(fā)標(biāo)記(CMS concurrent mark)琐脏,重新標(biāo)記(CMS remark)攒砖,并發(fā)清除(CMS concurrent sweep)


7、G1收集器

? ? G1是一款面向服務(wù)端應(yīng)用的垃圾收集器日裙。G1具備以下特點(diǎn):并行與并發(fā)吹艇,分代收集,空間整理昂拂,可預(yù)測的停頓受神。使用G1收集器時,Java堆的內(nèi)存布局就與其他收集器有很大差別格侯,它將整個Java堆劃分為多個大小相等的獨(dú)立區(qū)域(Region)鼻听,雖然還保留有新生代和老年代的概念,但新生代和老年代不再是物理隔離的了联四,它們都是一部分Region的集合撑碴。


四、內(nèi)存分配策略

? ? ? ? 對象的內(nèi)存分配朝墩,就是在堆上分配醉拓,對象主要分配在新生代Eden區(qū)上。

1收苏、對象優(yōu)先在Eden分配

? ? 大多數(shù)情況下亿卤,對象在新生代Eden區(qū)中分配。當(dāng)Eden區(qū)沒有足夠空間進(jìn)行分配時鹿霸,虛擬機(jī)將發(fā)起一次Minor GC怠噪。

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

? ? 所謂的大對象是指杜跷,需要大量連續(xù)內(nèi)存空間的Java對象傍念,最典型的就是那種很長的字符串以及數(shù)組。虛擬機(jī)提供了一個-XX:PretenureSizeThreshold參數(shù)葛闷,令大于這個設(shè)置值的對象直接在老年代分配憋槐。

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

? ? ? 虛擬機(jī)給每個對象定義了一個對象年齡計(jì)數(shù)器淑趾,對象在Survivor中每“熬過”一次Minor GC阳仔,年齡就增加1歲,當(dāng)它的年齡達(dá)到一定程度,就會晉升到老年代近范。對象晉升的閾值嘶摊,可以通過參數(shù)-XX:MaxTenuringThreshold設(shè)置。

4评矩、動態(tài)對象年齡判定

? ? ? 如果在Survivor空間中相同年齡所有對象的大小的總和大于Survivor空間的一半叶堆,年齡大于或者該年齡的對象就可以直接進(jìn)入老年代,無須等到XX:MaxTenuringThreshold中要求的年齡斥杜。

5虱颗、空間分配擔(dān)保

? ? 在發(fā)生Minor GC之前,虛擬機(jī)會先檢查老年代最大可用的連續(xù)空間是否大于新生代所有對象空間蔗喂,如果這個條件成立忘渔,那么Minor GC 可以確保是安全的。如果不成立缰儿,則虛擬機(jī)會查看HandlerPromotionFailure設(shè)置值是否允許擔(dān)保失敗畦粮。如果允許,那么會繼續(xù)檢查老年代最大可用的連續(xù)空間是否大于歷次晉升到老年代對象的平均大小乖阵,如果大于锈玉,將嘗試著進(jìn)行一次Minor GC,盡管這次Minor GC 是有風(fēng)險(xiǎn)的义起;如果小于,或者HandlerPromotionFailure設(shè)置不允許冒險(xiǎn)师崎,那么這時也要改為進(jìn)行一次Full GC默终。

本文來自于《深入Java虛擬機(jī)-JVM高級特性與最佳實(shí)踐》---周志明。如果侵權(quán)犁罩,請聯(lián)系作者刪除齐蔽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市床估,隨后出現(xiàn)的幾起案子含滴,更是在濱河造成了極大的恐慌,老刑警劉巖丐巫,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谈况,死亡現(xiàn)場離奇詭異,居然都是意外死亡递胧,警方通過查閱死者的電腦和手機(jī)碑韵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缎脾,“玉大人祝闻,你說我怎么就攤上這事∫挪ぃ” “怎么了联喘?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵华蜒,是天一觀的道長。 經(jīng)常有香客問我豁遭,道長叭喜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任堤框,我火速辦了婚禮域滥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜈抓。我一直安慰自己启绰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布沟使。 她就那樣靜靜地躺著委可,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腊嗡。 梳的紋絲不亂的頭發(fā)上着倾,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機(jī)與錄音燕少,去河邊找鬼卡者。 笑死,一個胖子當(dāng)著我的面吹牛客们,可吹牛的內(nèi)容都是我干的崇决。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼底挫,長吁一口氣:“原來是場噩夢啊……” “哼恒傻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起建邓,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤盈厘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后官边,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沸手,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年注簿,在試婚紗的時候發(fā)現(xiàn)自己被綠了罐氨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡滩援,死狀恐怖栅隐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤租悄,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布谨究,位于F島的核電站,受9級特大地震影響泣棋,放射性物質(zhì)發(fā)生泄漏胶哲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一潭辈、第九天 我趴在偏房一處隱蔽的房頂上張望鸯屿。 院中可真熱鬧,春花似錦把敢、人聲如沸寄摆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婶恼。三九已至,卻和暖如春柏副,著一層夾襖步出監(jiān)牢的瞬間勾邦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工割择, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留眷篇,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓荔泳,卻偏偏與公主長得像蕉饼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子换可,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評論 2 354

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