JVM學(xué)習(xí)筆記與調(diào)優(yōu)實(shí)戰(zhàn)(二):GC

標(biāo)簽: JVM


1、什么是可回收對象(垃圾)年柠?


畫圖演示

GC垃圾
GC垃圾


  • 引用:

    • 強(qiáng)引用:強(qiáng)引用指的是子啊程序代碼中普通存在的,類似Object obj = new Object()這類的引用,只要強(qiáng)引用還在溯壶,垃圾收集器則不會回收掉被引用的對象.

    • 軟引用:軟引用用于描述一些還有用但并非必需的對象。對于軟引用關(guān)聯(lián)著的對象甫男,在系統(tǒng)將要發(fā)生內(nèi)存溢出異常之前茸塞,將會把這些對象列進(jìn)回收范圍之中進(jìn)行第二次回收,如果這次回收還沒有足夠的內(nèi)存查剖,才會拋出內(nèi)存溢出異常钾虐,在jdk1.2之后,提供了SoftReference類來實(shí)現(xiàn)軟引用.

    • 弱引用:弱引用也是用于描述非必須對象笋庄,但是它的強(qiáng)度比軟引用更弱一些效扫,被弱引用關(guān)聯(lián)的對象只能生存到下一次垃圾收集發(fā)生之前。當(dāng)垃圾收集器工作時(shí)直砂,無論當(dāng)前內(nèi)存是否足夠菌仁,都會回收掉只被弱引用關(guān)聯(lián)的對象,在jdk1.2之后静暂,提供了WeakReference類來實(shí)現(xiàn)弱引用.

    • 虛引用:也稱為幽靈引用济丘、幻影引用,是最弱的一種引用關(guān)系洽蛀,一個(gè)對象是否有虛引用的存在盗冷,不會對其生成時(shí)間構(gòu)成影響,無法通過虛引用來引用對象隅居。為一個(gè)對象設(shè)置虛引用的目的是能在這個(gè)對象被收集器回收時(shí)收到一個(gè)系統(tǒng)通知须揣,jdk1.2提供PhantomReference類來實(shí)現(xiàn)虛引用.



2、GC是如何確定垃圾的驮审?

  • 引用計(jì)數(shù)法
    • 算法思路:給對象添加一個(gè)引用計(jì)數(shù)器鲫寄,每當(dāng)有一個(gè)地方引用它時(shí),計(jì)數(shù)器值加1疯淫;當(dāng)引用失效時(shí)地来,計(jì)數(shù)器值減1;任何時(shí)刻計(jì)數(shù)器為0的對象則是不可用的熙掺。

    • 引用計(jì)數(shù)算法(Reference Counting)的實(shí)現(xiàn)簡單未斑,判定效率也很高,但是無法解決循環(huán)引用問題

  • 可達(dá)性分析
    • 從roots對象計(jì)算可以達(dá)到的對象

    • 可作為GC Roots的對象包括:

      • 虛擬機(jī)棧(棧幀中的本地變量表)中引用的對象
      • 方法區(qū)中類靜態(tài)屬性引用的對象
      • 方法區(qū)中常量引用的對象
      • 本地方法棧中JNI引用的對象

    • 算法思路:以GC Roots 對象為起始點(diǎn)适掰,從這些節(jié)點(diǎn)開始向下搜索(深度搜索)颂碧,搜索所走過的路勁成為引用鏈(Reference Chain)荠列,當(dāng)一個(gè)對象到GCRoots不存在引用鏈(不可達(dá))時(shí),則證明此對象是不可用载城,即判定為可回收對象肌似。邏輯圖如下:

可達(dá)性分析
可達(dá)性分析



一種可能的物理內(nèi)存圖:

可達(dá)性分析內(nèi)存圖
可達(dá)性分析內(nèi)存圖

3、GC算法

  • Mark-Sweep標(biāo)記清除:
    • 算法分為標(biāo)記和清除兩個(gè)階段:首先標(biāo)記出所有需要回收的對象诉瓦,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對象川队,標(biāo)記過程通過可達(dá)性分析,將不可達(dá)的對象進(jìn)行標(biāo)記判定睬澡。

    • 不足之處:

      • 效率問題固额,標(biāo)記和清除兩個(gè)過程效率都不高
      • 空間問題,標(biāo)記清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片煞聪,空間碎片太多可能會導(dǎo)致后續(xù)需要分配較大內(nèi)存的對象時(shí)斗躏,無法找到足夠的連續(xù)內(nèi)存,而不得不提前觸發(fā)一次FGC


        標(biāo)記清除
        標(biāo)記清除


  • Copying復(fù)制:
    • 將內(nèi)存按容量劃分為大小相等的兩塊昔脯,每次只使用其中的一塊啄糙,當(dāng)這一塊的內(nèi)存用完了,就將還存活著的對象復(fù)制到另外一塊上面云稚,然后再把使用過的內(nèi)存空間一次清理掉隧饼。常用于新生代 survivor區(qū)的from/to的復(fù)制

    • 優(yōu)點(diǎn):在內(nèi)存上進(jìn)行復(fù)制效率高,不存在內(nèi)存碎片化問題

    • 缺點(diǎn):內(nèi)存空間利用率低静陈,算法代價(jià)高燕雁,因此實(shí)際分給新生代中的survivor區(qū)內(nèi)存較小,與Eden區(qū)比例約為8:1:1


      復(fù)制算法
      復(fù)制算法


  • Mark-Compact標(biāo)記壓縮:
    • 標(biāo)記過程仍然與標(biāo)記-清除算法一樣鲸拥,采用可達(dá)性分析標(biāo)記判定拐格,然后讓所有存活對象都向一端移動,然后直接清理掉端邊界以外的內(nèi)存崩泡。

    • 該算法效率略低于復(fù)制算法禁荒,但內(nèi)存空間利用率高猬膨,常用于老年代GC

標(biāo)記壓縮算法
標(biāo)記壓縮算法


  • 分代收集算法:當(dāng)前商業(yè)虛擬機(jī)的垃圾收集都采用分代收集(GenerationalCollection)算法,角撞,該算法根據(jù)對象存活周期的不同將堆內(nèi)存劃分為幾塊:新生代、老年代勃痴,然后根據(jù)各個(gè)年代的特點(diǎn)采用最適當(dāng)?shù)腉C算法:

    • 在新生代中谒所,每次GC時(shí)都發(fā)現(xiàn)有大量對象死去,只有少量存活沛申,則選用復(fù)制算法劣领,只需要付出少量存活對象的復(fù)制成本即可完成GC

    • 在老年代中,對象存活率高铁材、尖淘,沒有額外空間對它進(jìn)行分配擔(dān)保奕锌,則需要使用標(biāo)記-清除算法或者標(biāo)記-壓縮算法(默認(rèn)使用)進(jìn)行GC


4、垃圾收集器:翻譯自官方文檔

  • 串行收集器 Serial Collector:
    • 串行收集器使用單個(gè)線程執(zhí)行所有垃圾收集工作村生,這使得它相對高效惊暴,因?yàn)榫€程之間沒有通信開銷。它最適合于單處理器機(jī)器趁桃,因?yàn)樗荒芾枚嗵幚砥饔布苫埃M管對于具有小數(shù)據(jù)集(高達(dá)大約100 MB)的應(yīng)用程序,它可能對多處理器很有用卫病。串行收集器在某些硬件和操作系統(tǒng)配置中默認(rèn)選中油啤,或者可以使用該選項(xiàng)明確啟用-XX:+UseSerialGC。

    • XX:+UseSerialGC

    • 單線程

  • 并行收集器 Paraller Collector:
    • 官方文檔(翻譯):并行收集器(也稱為吞吐量收集器)并行執(zhí)行次要收集蟀苛,這可以顯著減少垃圾收集開銷益咬。它適用于在多處理器或多線程硬件上運(yùn)行的中型到大型數(shù)據(jù)集的應(yīng)用程序。并行收集器在某些硬件和操作系統(tǒng)配置上默認(rèn)選中帜平,或者可以使用該選項(xiàng)明確啟用-XX:+UseParallelGC础废。

    • 并行壓縮是一個(gè)使并行采集器能夠并行執(zhí)行主要采集的功能。如果沒有并行壓縮罕模,主要集合將使用單個(gè)線程執(zhí)行评腺,這可能會極大地限制可伸縮性。如果-XX:+UseParallelGC指定了選項(xiàng)淑掌,則默認(rèn)啟用并行壓縮蒿讥。關(guān)閉它的選項(xiàng)是-XX:-UseParallelOldGC。

    • 并發(fā)量大抛腕,每次GC時(shí)芋绸,JVM需要停頓

  • 并發(fā)收集器
    • CMS Collector: 此收集器適用于希望縮短垃圾收集暫停時(shí)間并能夠與垃圾收集共享處理器資源的應(yīng)用程序。

      • 停頓時(shí)間短
    • G1: 這種服務(wù)器式垃圾收集器適用于內(nèi)存較大的多處理器機(jī)器担敌。它以高概率滿足垃圾收集暫停時(shí)間目標(biāo)摔敛,同時(shí)實(shí)現(xiàn)高吞吐量。

      • 停頓短全封,同時(shí)并發(fā)大

  • 并發(fā)開銷:
    • 大多數(shù)并發(fā)收集器交換處理器資源(否則可用于應(yīng)用程序)以縮短主要收集暫停時(shí)間马昙。最明顯的開銷是在收集的并發(fā)部分期間使用一個(gè)或多個(gè)處理器。在N處理器系統(tǒng)上刹悴,并發(fā)部分集合將使用可用處理器的K / N行楞,其中1 <= K <= ceiling { N / 4}。(注意K上的精確選擇和邊界)除了在并行階段使用處理器之外土匀,還會產(chǎn)生額外的開銷以實(shí)現(xiàn)并發(fā)子房。因此,雖然垃圾收集暫停通常比并發(fā)收集器短得多,但應(yīng)用程序吞吐量也往往略低于其他收集器证杭。

    • 在具有多個(gè)處理核心的計(jì)算機(jī)上田度,處理器可用于集合并發(fā)部分中的應(yīng)用程序線程,因此并發(fā)垃圾收集器線程不會“暫徒夥撸”應(yīng)用程序每币。這通常會導(dǎo)致更短的暫停,但是應(yīng)用程序可用的處理器資源也較少琢歇,應(yīng)該會出現(xiàn)一些減速兰怠,特別是在應(yīng)用程序最大限度地使用所有處理內(nèi)核的情況下。隨著N的增加李茫,由于并發(fā)垃圾收集導(dǎo)致的處理器資源減少變得更小揭保,同時(shí)收集的收益也增加。的部分并行模故障在并發(fā)標(biāo)記掃描(CMS)集電極討論了這樣的縮放潛在限制魄宏。

    • 由于至少有一個(gè)處理器用于并發(fā)階段的垃圾收集秸侣,因此并發(fā)收集器通常不會為單處理器(單核)機(jī)器提供任何好處。但是宠互,對于CMS(不是G1)味榛,可以使用單獨(dú)的模式,可以在只有一個(gè)或兩個(gè)處理器的系統(tǒng)上實(shí)現(xiàn)低暫停; 看到增量模式在并發(fā)標(biāo)記掃描(CMS)收集器的詳細(xì)信息予跌。此功能在Java SE 8中不推薦使用搏色,并可能在以后的主要版本中刪除。

  • 選擇收集器:除非應(yīng)用程序具有相當(dāng)嚴(yán)格的暫停時(shí)間要求券册,否則請先運(yùn)行您的應(yīng)用程序并允許VM選擇收集器频轿。如有必要,請調(diào)整堆大小以提高性能烁焙。如果性能仍不能達(dá)到您的目標(biāo)航邢,請使用以下指南作為選擇收集器的起點(diǎn)。
    • 如果應(yīng)用程序有一個(gè)小數(shù)據(jù)集(最多大約100MB)骄蝇,那么用選項(xiàng)選擇串行收集器-XX:+UseSerialGC膳殷。

    • 如果應(yīng)用程序?qū)⒃趩蝹€(gè)處理器上運(yùn)行,并且沒有暫停時(shí)間要求九火,則讓VM選擇收集器赚窃,或者使用該選項(xiàng)選擇串行收集器-XX:+UseSerialGC。

    • 如果(a)峰值應(yīng)用程序性能是第一優(yōu)先級并且(b)沒有暫停時(shí)間要求或暫停1秒或更長時(shí)間是可接受的吃既,則讓VM選擇收集器考榨,或者選擇并行收集器-XX:+UseParallelGC。

    • 如果響應(yīng)時(shí)間比整體吞吐量更重要鹦倚,并且垃圾收集暫停時(shí)間必須短于大約1秒,那么使用-XX:+UseConcMarkSweepGC或選擇并發(fā)收集器-XX:+UseG1GC冀惭。

    • 如果推薦的收集器無法達(dá)到所需的性能震叙,請首先嘗試調(diào)整堆和代的大小以達(dá)到所需的目標(biāo)掀鹅。如果性能仍然不足,請嘗試使用其他收集器:使用并發(fā)收集器來減少暫停時(shí)間媒楼,并使用并行收集器來提高多處理器硬件的整體吞吐量乐尊。


參考資料:
1.《深入理解Java虛擬機(jī)》
2.官方文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市划址,隨后出現(xiàn)的幾起案子扔嵌,更是在濱河造成了極大的恐慌,老刑警劉巖夺颤,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痢缎,死亡現(xiàn)場離奇詭異,居然都是意外死亡世澜,警方通過查閱死者的電腦和手機(jī)独旷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寥裂,“玉大人嵌洼,你說我怎么就攤上這事》馇。” “怎么了麻养?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诺舔。 經(jīng)常有香客問我回溺,道長,這世上最難降的妖魔是什么混萝? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任遗遵,我火速辦了婚禮,結(jié)果婚禮上逸嘀,老公的妹妹穿的比我還像新娘车要。我一直安慰自己,他們只是感情好崭倘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布翼岁。 她就那樣靜靜地躺著,像睡著了一般司光。 火紅的嫁衣襯著肌膚如雪琅坡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天残家,我揣著相機(jī)與錄音榆俺,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛茴晋,可吹牛的內(nèi)容都是我干的陪捷。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼诺擅,長吁一口氣:“原來是場噩夢啊……” “哼市袖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起烁涌,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤苍碟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后撮执,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體微峰,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年二打,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了县忌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,683評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡继效,死狀恐怖症杏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瑞信,我是刑警寧澤厉颤,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站凡简,受9級特大地震影響逼友,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秤涩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一帜乞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧筐眷,春花似錦黎烈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至武翎,卻和暖如春烈炭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宝恶。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工符隙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留趴捅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓膏执,卻偏偏與公主長得像驻售,于是被迫代替她去往敵國和親露久。 傳聞我的和親對象是個(gè)殘疾皇子更米,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評論 2 349

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