關于JAVA GC 的所有

在學習GC之前,你首先應該記住一個單詞:“stop-the-world”。Stop-the-world會在任何一種GC算法中發(fā)生。Stop-the-world意味著 JVM 因為要執(zhí)行GC而停止了應用程序的執(zhí)行淋叶。當Stop-the-world發(fā)生時,除了GC所需的線程以外伪阶,所有線程都處于等待狀態(tài)煞檩,直到GC任務完成。GC優(yōu)化很多時候就是指減少Stop-the-world發(fā)生的時間栅贴。

引用來源http://edu.gamfe.com/tutorial/search.aspx?info=%u5404%u79CD%u5783%u573E%u56DE%u6536%u7B97%u6CD5/

引用計數(shù)( Reference Counting )算法 1960

年以前斟湃,人們?yōu)榕咛ブ械?Lisp 語言設計垃圾收集機制時,第一個想到的算法是引用計數(shù)算法檐薯。拿餐巾紙的例子來說凝赛,這種算法的原理大致可以描述為:
午餐時注暗,為了把腦子里突然跳出來的設計靈感記下來,我從餐巾紙袋中抽出一張餐巾紙墓猎,打算在上面畫出系統(tǒng)架構的藍圖捆昏。按照“餐巾紙使用規(guī)約之引用計數(shù)版”的要求,畫圖之前毙沾,我必須先在餐巾紙的一角寫上計數(shù)值 1 骗卜,以表示我在使用這張餐巾紙。這時左胞,如果你也想看看我畫的藍圖膨俐,那你就要把餐巾紙上的計數(shù)值加 1 ,將它改為 2 罩句,這表明目前有 2個人在同時使用這張餐巾紙(當然,我是不會允許你用這張餐巾紙來擦鼻涕的)敛摘。你看完后门烂,必須把計數(shù)值減 1 ,表明你對該餐巾紙的使用已經結束兄淫。同樣屯远,當我將餐巾紙上的內容全部謄寫到筆記本上之后,我也會自覺地把餐巾紙上的計數(shù)值減 1 捕虽。此時慨丐,不出意外的話,這張餐巾紙上的計數(shù)值應當是 0 泄私,它會被垃圾收集器——假設那是一個專門負責打掃衛(wèi)生的機器人——撿起來扔到垃圾箱里房揭,因為垃圾收集器的惟一使命就是找到所有計數(shù)值為 0 的餐巾紙并清理它們。

引用計數(shù)算法的優(yōu)點和缺陷同樣明顯晌端。這一算法在執(zhí)行垃圾收集任務時速度較快捅暴,但算法對程序中每一次內存分配和指針操作提出了額外的要求(增加或減少內存塊的引用計數(shù))。更重要的是咧纠,引用計數(shù)算法無法正確釋放循環(huán)引用的內存塊蓬痒,對此, D. Hillis 有一段風趣而精辟的論述:

一天漆羔,一個學生走到 Moon 面前說:“我知道如何設計一個更好的垃圾收集器了梧奢。我們必須記錄指向每個結點的指針數(shù)目⊙菅鳎” Moon 耐心地給這位學生講了下面這個故事:“一天亲轨,一個學生走到 Moon 面前說:‘我知道如何設計一個更好的垃圾收集器了

……’” D. Hillis 的故事和我們小時候常說的“從前有座山,山上有個廟鸟顺,廟里有個老和尚”的故事有異曲同工之妙瓶埋。這說明,單是使用引用計數(shù)算法還不足以解決垃圾收集中的所有問題。正因為如此养筒,引用計數(shù)算法也常常被研究者們排除在狹義的垃圾收集算法之外曾撤。當然,作為一種最簡單晕粪、最直觀的解決方案挤悉,引用計數(shù)算法本身具有其不可替代的優(yōu)越性。 1980年代前后巫湘, D. P. Friedman 装悲, D. S. Wise , H. G. Baker 等人對引用計數(shù)算法進行了數(shù)次改進尚氛,這些改進使得引用計數(shù)算法及其變種(如延遲計數(shù)算法等)在簡單的環(huán)境下诀诊,或是在一些綜合了多種算法的現(xiàn)代垃圾收集系統(tǒng)中仍然可以一展身手。

標記-清除( Mark-Sweep )算法
第一種實用和完善的垃圾收集算法是 J. McCarthy 等人在 1960 年提出并成功地應用于 Lisp 語言的標記-清除算法阅嘶。仍以餐巾紙為例属瓣,標記-清除算法的執(zhí)行過程是這樣的:
午餐過程中,餐廳里的所有人都根據(jù)自己的需要取用餐巾紙讯柔。當垃圾收集機器人想收集廢舊餐巾紙的時候抡蛙,它會讓所有用餐的人先停下來,然后魂迄,依次詢問餐廳里的每一個人:“你正在用餐巾紙嗎粗截?你用的是哪一張餐巾紙?”機器人根據(jù)每個人的回答將人們正在使用的餐巾紙畫上記號捣炬。詢問過程結束后熊昌,機器人在餐廳里尋找所有散落在餐桌上且沒有記號的餐巾紙(這些顯然都是用過的廢舊餐巾紙),把它們統(tǒng)統(tǒng)扔到垃圾箱里湿酸。
正如其名稱所暗示的那樣浴捆,標記-清除算法的執(zhí)行過程分為“標記”和“清除”兩大階段。這種分步執(zhí)行的思路奠定了現(xiàn)代垃圾收集算法的思想基礎稿械。與引用計數(shù)算法不同的是选泻,標記-清除算法不需要運行環(huán)境監(jiān)測每一次內存分配和指針操作,而只要在“標記”階段中跟蹤每一個指針變量的指向——用類似思路實現(xiàn)的垃圾收集器也常被后人統(tǒng)稱為跟蹤收集器( Tracing Collector )
伴隨著 Lisp 語言的成功美莫,標記-清除算法也在大多數(shù)早期的 Lisp 運行環(huán)境中大放異彩页眯。盡管最初版本的標記-清除算法在今天看來還存在效率不高(標記和清除是兩個相當耗時的過程)等諸多缺陷,但在后面的討論中厢呵,我們可以看到窝撵,幾乎所有現(xiàn)代垃圾收集算法都是標記-清除思想的延續(xù),僅此一點襟铭, J. McCarthy 等人在垃圾收集技術方面的貢獻就絲毫不亞于他們在 Lisp 語言上的成就了碌奉。

復制( Copying )算法
為了解決標記-清除算法在垃圾收集效率方面的缺陷短曾, M. L. Minsky 于 1963 年發(fā)表了著名的論文“一種使用雙存儲區(qū)的 Lisp 語言垃圾收集器( A LISP Garbage Collector Algorithm Using Serial Secondary Storage )”。 M. L. Minsky 在該論文中描述的算法被人們稱為復制算法赐劣,它也被 M. L. Minsky 本人成功地引入到了 Lisp 語言的一個實現(xiàn)版本中嫉拐。
復制算法別出心裁地將堆空間一分為二,并使用簡單的復制操作來完成垃圾收集工作魁兼,這個思路相當有趣婉徘。借用餐巾紙的比喻,我們可以這樣理解 M. L. Minsky 的復制算法:
餐廳被垃圾收集機器人分成南區(qū)和北區(qū)兩個大小完全相同的部分咐汞。午餐時盖呼,所有人都先在南區(qū)用餐(因為空間有限,用餐人數(shù)自然也將減少一半)化撕,用餐時可以隨意使用餐巾紙几晤。當垃圾收集機器人認為有必要回收廢舊餐巾紙時,它會要求所有用餐者以最快的速度從南區(qū)轉移到北區(qū)植阴,同時隨身攜帶自己正在使用的餐巾紙蟹瘾。等所有人都轉移到北區(qū)之后,垃圾收集機器人只要簡單地把南區(qū)中所有散落的餐巾紙扔進垃圾箱就算完成任務了墙贱。下一次垃圾收集的工作過程也大致類似,惟一的不同只是人們的轉移方向變成了從北區(qū)到南區(qū)贱傀。如此循環(huán)往復惨撇,每次垃圾收集都只需簡單地轉移(也就是復制)一次,垃圾收集速度無與倫比——當然府寒,對于用餐者往返奔波于南北兩區(qū)之間的辛勞魁衙,垃圾收集機器人是決不會流露出絲毫憐憫的。
M. L. Minsky 的發(fā)明絕對算得上一種奇思妙想株搔。分區(qū)剖淀、復制的思路不僅大幅提高了垃圾收集的效率,而且也將原本繁紛復雜的內存分配算法變得前所未有地簡明和扼要(既然每次內存回收都是對整個半?yún)^(qū)的回收纤房,內存分配時也就不用考慮內存碎片等復雜情況纵隔,只要移動堆頂指針,按順序分配內存就可以了)炮姨,這簡直是個奇跡捌刮!不過,任何奇跡的出現(xiàn)都有一定的代價舒岸,在垃圾收集技術中绅作,復制算法提高效率的代價是人為地將可用內存縮小了一半。實話實說蛾派,這個代價未免也太高了一些俄认。

標記-整理( Mark-Compact )算法
標記-整理算法是標記-清除算法和復制算法的有機結合个少。把標記-清除算法在內存占用上的優(yōu)點和復制算法在執(zhí)行效率上的特長綜合起來,這是所有人都希望看到的結果眯杏。不過夜焦,兩種垃圾收集算法的整合并不像 1 加 1 等于 2 那樣簡單,我們必須引入一些全新的思路役拴。 1970 年前后糊探, G. L. Steele , C. J. Cheney 和 D. S. Wise 等研究者陸續(xù)找到了正確的方向河闰,標記-整理算法的輪廓也逐漸清晰了起來:
在我們熟悉的餐廳里科平,這一次,垃圾收集機器人不再把餐廳分成兩個南北區(qū)域了姜性。需要執(zhí)行垃圾收集任務時瞪慧,機器人先執(zhí)行標記-清除算法的第一個步驟,為所有使用中的餐巾紙畫好標記部念,然后弃酌,機器人命令所有就餐者帶上有標記的餐巾紙向餐廳的南面集中,同時把沒有標記的廢舊餐巾紙扔向餐廳北面儡炼。這樣一來妓湘,機器人只消站在餐廳北面,懷抱垃圾箱乌询,迎接撲面而來的廢舊餐巾紙就行了榜贴。
實驗表明,標記-整理算法的總體執(zhí)行效率高于標記-清除算法妹田,又不像復制算法那樣需要犧牲一半的存儲空間唬党,這顯然是一種非常理想的結果。在許多現(xiàn)代的垃圾收集器中鬼佣,人們都使用了標記-整理算法或其改進版本驶拱。

增量收集( Incremental Collecting )算法
對實時垃圾收集算法的研究直接導致了增量收集算法的誕生。
最初晶衷,人們關于實時垃圾收集的想法是這樣的:為了進行實時的垃圾收集蓝纲,可以設計一個多進程的運行環(huán)境,比如用一個進程執(zhí)行垃圾收集工作晌纫,另一個進程執(zhí)行程序代碼驻龟。這樣一來,垃圾收集工作看上去就仿佛是在后臺悄悄完成的缸匪,不會打斷程序代碼的運行翁狐。
在收集餐巾紙的例子中,這一思路可以被理解為:垃圾收集機器人在人們用餐的同時尋找廢棄的餐巾紙并將它們扔到垃圾箱里凌蔬。這個看似簡單的思路會在設計和實現(xiàn)時碰上進程間沖突的難題露懒。比如說闯冷,如果垃圾收集進程包括標記和清除兩個工作階段,那么懈词,垃圾收集器在第一階段中辛辛苦苦標記出的結果很可能被另一個進程中的內存操作代碼修改得面目全非蛇耀,以至于第二階段的工作沒有辦法開展。
M. L. Minsky 和 D. E. Knuth 對實時垃圾收集過程中的技術難點進行了早期的研究坎弯, G. L. Steele 于 1975 年發(fā)表了題為“多進程整理的垃圾收集( Multiprocessing compactifying garbage collection )”的論文纺涤,描述了一種被后人稱為“ Minsky-Knuth-Steele 算法”的實時垃圾收集算法。 E. W. Dijkstra 抠忘, L. Lamport 撩炊, R. R. Fenichel 和 J. C. Yochelson 等人也相繼在此領域做出了各自的貢獻。 1978 年崎脉, H. G. Baker 發(fā)表了“串行計算機上的實時表處理技術( List Processing in Real Time on a Serial Computer )”一文拧咳,系統(tǒng)闡述了多進程環(huán)境下用于垃圾收集的增量收集算法。
增量收集算法的基礎仍是傳統(tǒng)的標記-清除和復制算法囚灼。增量收集算法通過對進程間沖突的妥善處理骆膝,允許垃圾收集進程以分階段的方式完成標記、清理或復制工作灶体。詳細分析各種增量收集算法的內部機理是一件相當繁瑣的事情阅签,在這里,讀者們需要了解的僅僅是: H. G. Baker 等人的努力已經將實時垃圾收集的夢想變成了現(xiàn)實蝎抽,我們再也不用為垃圾收集打斷程序的運行而煩惱了

分代收集( Generational Collecting )算法
和大多數(shù)軟件開發(fā)技術一樣政钟,統(tǒng)計學原理總能在技術發(fā)展的過程中起到強力催化劑的作用。 1980 年前后织中,善于在研究中使用統(tǒng)計分析知識的技術人員發(fā)現(xiàn)锥涕,大多數(shù)內存塊的生存周期都比較短衷戈,垃圾收集器應當把更多的精力放在檢查和清理新分配的內存塊上狭吼。這個發(fā)現(xiàn)對于垃圾收集技術的價值可以用餐巾紙的例子概括如下:
如果垃圾收集機器人足夠聰明,事先摸清了餐廳里每個人在用餐時使用餐巾紙的習慣——比如有些人喜歡在用餐前后各用掉一張餐巾紙殖妇,有的人喜歡自始至終攥著一張餐巾紙不放刁笙,有的人則每打一個噴嚏就用去一張餐巾紙——機器人就可以制定出更完善的餐巾紙回收計劃,并總是在人們剛扔掉餐巾紙沒多久就把垃圾撿走谦趣。這種基于統(tǒng)計學原理的做法當然可以讓餐廳的整潔度成倍提高疲吸。
D. E. Knuth , T. Knight 前鹅, G. Sussman 和 R. Stallman 等人對內存垃圾的分類處理做了最早的研究摘悴。 1983 年, H. Lieberman 和 C. Hewitt 發(fā)表了題為“基于對象壽命的一種實時垃圾收集器( A real-time garbage collector based on the lifetimes of objects )”的論文舰绘。這篇著名的論文標志著分代收集算法的正式誕生蹂喻。此后葱椭,在 H. G. Baker , R. L. Hudson 口四, J. E. B. Moss 等人的共同努力下孵运,分代收集算法逐漸成為了垃圾收集領域里的主流技術。
分代收集算法通常將堆中的內存塊按壽命分為兩類蔓彩,年老的和年輕的治笨。垃圾收集器使用不同的收集算法或收集策略,分別處理這兩類內存塊赤嚼,并特別地把主要工作時間花在處理年輕的內存塊上旷赖。分代收集算法使垃圾收集器在有限的資源條件下,可以更為有效地工作——這種效率上的提高在今天的 Java 虛擬機中得到了最好的證明探膊。

教程1是分代收集算法的一個很好的解釋和闡述

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末杠愧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子逞壁,更是在濱河造成了極大的恐慌流济,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腌闯,死亡現(xiàn)場離奇詭異绳瘟,居然都是意外死亡加矛,警方通過查閱死者的電腦和手機硅急,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門罢洲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闪彼,“玉大人弱判,你說我怎么就攤上這事银锻∈愁恚” “怎么了脱篙?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵嘲玫,是天一觀的道長悦施。 經常有香客問我,道長去团,這世上最難降的妖魔是什么抡诞? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮土陪,結果婚禮上昼汗,老公的妹妹穿的比我還像新娘。我一直安慰自己鬼雀,他們只是感情好顷窒,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著源哩,像睡著了一般鞋吉。 火紅的嫁衣襯著肌膚如雪出刷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天坯辩,我揣著相機與錄音馁龟,去河邊找鬼。 笑死漆魔,一個胖子當著我的面吹牛坷檩,可吹牛的內容都是我干的。 我是一名探鬼主播改抡,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼矢炼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了阿纤?” 一聲冷哼從身側響起句灌,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎欠拾,沒想到半個月后胰锌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡藐窄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年资昧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荆忍。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡格带,死狀恐怖,靈堂內的尸體忽然破棺而出刹枉,到底是詐尸還是另有隱情叽唱,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布微宝,位于F島的核電站棺亭,受9級特大地震影響,放射性物質發(fā)生泄漏芥吟。R本人自食惡果不足惜侦铜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一专甩、第九天 我趴在偏房一處隱蔽的房頂上張望钟鸵。 院中可真熱鬧,春花似錦涤躲、人聲如沸棺耍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒙袍。三九已至俊卤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間害幅,已是汗流浹背消恍。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留以现,地道東北人狠怨。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像邑遏,于是被迫代替她去往敵國和親佣赖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內容

  • 1.什么是垃圾回收记盒? 垃圾回收(Garbage Collection)是Java虛擬機(JVM)垃圾回收器提供...
    簡欲明心閱讀 89,492評論 17 311
  • 《深入理解Java虛擬機》筆記_第一遍 先取看完這本書(JVM)后必須掌握的部分憎蛤。 第一部分 走近 Java 從傳...
    xiaogmail閱讀 5,087評論 1 34
  • 原文閱讀 前言 這段時間懈怠了,罪過纪吮! 最近看到有同事也開始用上了微信公眾號寫博客了俩檬,挺好的~給他們點贊,這博客我...
    碼農戲碼閱讀 5,962評論 2 31
  • 一. 垃圾回收的意義 在C++中碾盟,對象所占的內存在程序結束運行之前一直被占用豆胸,在明確釋放之前不能分配給其它對...
    Stan_Z閱讀 1,931評論 0 25
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡上收集的一些資料的整理,因此不免有一些不準確的地方巷疼,同時不同JDK版本的...
    高廣超閱讀 15,599評論 3 83