了解Java垃圾收集(GC)

了解Java中的垃圾回收(GC)的工作原理有什么好處侈贷?滿足軟件工程師的求知欲是一個正當?shù)睦碛桑粌H如此加匈,了解GC的工作原理也可以幫助您編寫更好的Java應(yīng)用程序洞辣。

這是我個人的非常主觀的看法,但是我相信精通GC的人往往是更好的Java開發(fā)人員码俩。如果您對GC流程感興趣度帮,則意味著您具有開發(fā)特定大小的應(yīng)用程序的經(jīng)驗。如果您仔細地考慮過選擇正確的GC算法稿存,則意味著您完全了解所開發(fā)應(yīng)用程序的功能笨篷。當然瞳秽,對于優(yōu)秀的開發(fā)人員來說,這可能不是通用的標準率翅。但是练俐,當我說理解GC是成為一名出色的Java開發(fā)人員的要求時,很少有人會反對安聘。?

這是“?成為Java GC專家?”系列文章中的第一篇痰洒。這次我將介紹GC,在下一篇文章中浴韭,我將討論分析特定的GC狀態(tài)和調(diào)優(yōu)示例。

在學(xué)習(xí)GC之前脯宿,您應(yīng)該了解一個術(shù)語念颈。術(shù)語是STW(?Stop The World?)。意味著JVM需要停止運行應(yīng)用程序以執(zhí)行GC连霉。這意味著除GC所需的線程以外的所有線程都將停止其任務(wù)榴芳,無法處理外部響應(yīng)。跺撼。被中斷的任務(wù)將僅在GC任務(wù)完成后才能恢復(fù)窟感。無論您選擇哪種GC算法,STW都會發(fā)生歉井。GC調(diào)優(yōu)通常意味著減少STW時間柿祈。

分代垃圾收集?

Java沒有顯式釋放內(nèi)存的操作。有人將相關(guān)對象設(shè)置為null或使用System.gc()方法顯式釋放內(nèi)存哩至,這是不合適的躏嚎。調(diào)用System.gc()方法將觸發(fā)垃圾回收,極大地影響系統(tǒng)性能菩貌。將對象設(shè)為null其實在大多種場景下沒有任何意義卢佣。

在Java中,由于開發(fā)人員未明確刪除程序代碼中的內(nèi)存箭阶,因此垃圾收集器會找到不再需要的(垃圾)對象并將其刪除虚茶。該垃圾收集器是基于以下兩個假設(shè)創(chuàng)建的。

1仇参、大多數(shù)新創(chuàng)建的對象生命周期都很短

2嘹叫、從老對象到新對象的引用數(shù)量很少。

這些假設(shè)稱為分代假設(shè)冈敛〈Γ基于此,在HotSpot VM實現(xiàn)中將其從物理上分為年輕代老年代抓谴。

年輕代(Yong Gen):大多數(shù)新創(chuàng)建的對象都位于此處暮蹂。由于大多數(shù)對象很快變得無法訪問寞缝,因此許多對象是在年輕一代中創(chuàng)建的,然后死亡了仰泻。當回收年輕代對象時荆陆,我們稱之為“ Minor?GC?”。

年老代(Old Gen):從年輕代幸存下來的對象復(fù)制到此處集侯。它通常比年輕一代大被啼。同時一些大對象也在此分配。由于它的大小較大棠枉,因此與年輕一代相比浓体,GC發(fā)生的頻率會降低,耗時會更久辈讶。當回收老年代對象時命浴,我們說發(fā)生了“? Major?GC?”(或“ Full?GC?”)。

見下圖:

圖1:GC區(qū)域和數(shù)據(jù)流贱除。

上表中的永久代也稱為“?方法區(qū)域?”生闲,它存儲類或長量字符串。在該區(qū)域可能會發(fā)生GC月幌,此處發(fā)生的GC仍被視為Major GC(Full GC)碍讯。?

有人可能會懷疑:

如果老一代的對象需要引用年輕一代的對象怎么辦?

為了處理這些情況扯躺,在年老代中有一個稱為“?卡片表?”的東西捉兴,它是一個512字節(jié)的塊。每當年老代中的對象引用年輕一代中的對象時缅帘,該對象都會記錄在此表中轴术。當為年輕代執(zhí)行GC時,僅搜索此卡表以確定它是否適用于GC钦无,而不是檢查年老代中所有對象的引用逗栽。

圖2:卡片表結(jié)構(gòu)。

年輕代的組成

年輕代是第一次創(chuàng)建對象的地方失暂。年輕一代分為3個空間彼宠。?

一個 Eden區(qū)

兩個 Survivor(From,To)區(qū)

總共有3個區(qū)弟塞,其中兩個是幸存者區(qū)凭峡。每個區(qū)的執(zhí)行過程順序如下:

1、大多數(shù)新創(chuàng)建的對象位于Eden區(qū)中决记。

2摧冀、在Eden區(qū)中進行一次GC之后,將幸存的對象移動到其中一個Survivor區(qū)。?

3索昂、在Eden區(qū)進行GC之后建车,將這些對象堆積到Survivor區(qū)中,該區(qū)中已經(jīng)存在其他幸存的物體椒惨。

4缤至、一旦Survivor區(qū)已滿,就將幸存對象移動到另一個Survivor區(qū)康谆。然后领斥,已滿的Survivor區(qū)將更改為完全沒有數(shù)據(jù)的狀態(tài)。

在這些步驟中幸存下來的對象(已重復(fù)多次)被移到了年老代沃暗。

通過檢查這些步驟可以看到月洛,Survivor區(qū)之一必須保持為空。

下表顯示了通過次要GC收集到舊數(shù)據(jù)中的數(shù)據(jù)的過程:

圖3:GC前和后孽锥。

在HotSpot VM中膊存,使用兩種技術(shù)來加快內(nèi)存分配。一個稱為“?碰撞指針?”忱叭,另一個稱為“?TLAB(線程本地分配緩沖區(qū))”。?

指針碰撞技術(shù)跟蹤分配給Eden區(qū)的最后一個對象今艺。該物體將位于Eden區(qū)的頂部韵丑。并且如果之后創(chuàng)建了一個對象,則僅檢查該對象的大小是否適合Eden空間虚缎。如果上述對象看起來正確撵彻,它將被放置在Eden空間中,新對象將位于頂部实牡。因此陌僵,在創(chuàng)建新對象時,僅需要檢查最后添加的對象创坞,從而可以更快地分配內(nèi)存碗短。但是,如果我們考慮多線程環(huán)境题涨,則情況就不同了偎谁。為了將多個線程使用的對象保存在Eden空間中以確保線程安全,將發(fā)生不可避免的鎖定纲堵,并且由于鎖定競爭而導(dǎo)致性能下降巡雨。TLAB?是HotSpot VM中解決此問題的方法。這允許每個線程在其Eden空間中有一小部分與其對應(yīng)的份額相對應(yīng)席函。由于每個線程只能訪問自己的TLAB铐望,因此即使是“撞球指針”技術(shù)也可以在沒有鎖的情況下分配內(nèi)存。?

年老代GC

當堆空間不夠用時會發(fā)生年老代GC。年老代GC的執(zhí)行過程根據(jù)GC策略類型的不同區(qū)別很大正蛙。對于JDK 7督弓,8,有5種GC類型跟畅。?

1咽筋、Serial GC - 串行GC

2、Parallel GC - 并行GC

3徊件、Parallel Old GC (Parallel Compacting GC)?

4奸攻、Concurrent Mark & Sweep GC ?(or "CMS")?

5、Garbage First (G1) GC

其中虱痕,Serial GC不得在運行服務(wù)器上使用睹耐。當臺式計算機上只有一個CPU內(nèi)核時,就會創(chuàng)建此GC類型部翘。使用此串行GC將大大降低應(yīng)用程序性能硝训。?

現(xiàn)在讓我們了解每種GC類型。

串行GC(-XX:+ UseSerialGC)

年輕一代中的GC使用我們在上一段中介紹的類型新思。老一代的GC使用一種稱為“?mark-sweep-compact?”?的算法窖梁。

標記-清除-整理算法會將清理后的堆的整理成連續(xù)的內(nèi)存空間。

串行GC適用于較小的內(nèi)存和少量的CPU內(nèi)核夹囚。


并行GC(-XX:+ UseParallelGC)

圖4:串行GC和并行GC之間的區(qū)別纵刘。

從圖片中,您可以輕松地看到串行GC和并行GC之間的區(qū)別荸哟。串行GC僅使用一個線程來處理GC假哎,而并行GC使用多個線程來處理GC,因此速度更快鞍历。當有足夠的內(nèi)存和大量內(nèi)核時舵抹,此GC很有用。也稱為“?吞吐量GC”劣砍。?

并行舊GC(-XX:+ UseParallelOldGC)

從JDK5開始支持惧蛹。與并行GC相比,唯一的區(qū)別是年老代的GC算法相對復(fù)雜秆剪。它經(jīng)歷了三個步驟:標記–摘要–整理赊淑。

CMS GC(-XX:+ UseConcMarkSweepGC)

圖5:串行GC和CMS GC

從圖片中可以看到,CMS比到目前為止我所解釋的任何其他GC類型都要復(fù)雜得多仅讽。早期的初始標記步驟很簡單陶缺。在最接近類加載器的對象中搜索尚存的對象。因此洁灵,暫停時間很短饱岸。在并發(fā)標記步驟中掺出,跟蹤并檢查了剛被確認的存活對象所引用的對象。此步驟的不同之處在于苫费,它是在同時處理其他線程的同時進行的汤锨。在重新標記步驟中,將檢查并發(fā)標記步驟中新添加或停止引用的對象百框。最后闲礼,在并發(fā)收集中步驟,將執(zhí)行垃圾收集過程铐维。在仍在處理其他線程時執(zhí)行垃圾回收柬泽。由于以這種方式執(zhí)行此GC類型,因此GC的暫停時間非常短嫁蛇。CMS GC也稱為低延遲GC锨并,在所有應(yīng)用程序的響應(yīng)時間至關(guān)重要時使用。?

CMS的一大有點是縮短了STW時間睬棚,但它也具有以下缺點:

1第煮、它比其他GC類型使用更多的內(nèi)存和CPU。

2抑党、默認情況下不提供壓縮步驟包警,容易導(dǎo)致內(nèi)存碎片

使用此類型之前,您需要仔細檢查底靠。另外揽趾,如果由于內(nèi)存碎片過多而需要執(zhí)行壓縮任務(wù),那么STW時間可能比任何其他GC類型都要長苛骨。您需要檢查壓縮任務(wù)執(zhí)行的頻率和時間。

G1 GC

最后苟呐,讓我們了解G1 GC痒芝。?

圖6:G1 GC的布局。

如果您想了解G1 GC牵素,請忘記所有有關(guān)年輕一代和老一代的知識严衬。如您在圖片中看到的,將一個對象分配給每個Region笆呆,然后執(zhí)行GC请琳。G1 GC是基于停頓時間為目標的回收算法,以最大程度的減少STW

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赠幕,一起剝皮案震驚了整個濱河市俄精,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌榕堰,老刑警劉巖竖慧,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫌套,死亡現(xiàn)場離奇詭異,居然都是意外死亡圾旨,警方通過查閱死者的電腦和手機踱讨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來砍的,“玉大人痹筛,你說我怎么就攤上這事±希” “怎么了帚稠?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诫惭。 經(jīng)常有香客問我翁锡,道長,這世上最難降的妖魔是什么夕土? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任馆衔,我火速辦了婚禮,結(jié)果婚禮上怨绣,老公的妹妹穿的比我還像新娘角溃。我一直安慰自己,他們只是感情好篮撑,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布减细。 她就那樣靜靜地躺著,像睡著了一般赢笨。 火紅的嫁衣襯著肌膚如雪未蝌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天茧妒,我揣著相機與錄音萧吠,去河邊找鬼。 笑死桐筏,一個胖子當著我的面吹牛纸型,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梅忌,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼狰腌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了牧氮?” 一聲冷哼從身側(cè)響起琼腔,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎踱葛,沒想到半個月后展姐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體躁垛,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年圾笨,在試婚紗的時候發(fā)現(xiàn)自己被綠了教馆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡擂达,死狀恐怖土铺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情板鬓,我是刑警寧澤悲敷,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站俭令,受9級特大地震影響后德,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抄腔,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一瓢湃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赫蛇,春花似錦绵患、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至暂幼,卻和暖如春筏勒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背旺嬉。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工奏寨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鹰服。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像揽咕,于是被迫代替她去往敵國和親悲酷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

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