java垃圾收集

轉(zhuǎn)載、引用請(qǐng)標(biāo)明出處
http://www.itdecent.cn/p/8ec0ee8ca7ee
本文出自zhh_happig的簡書博客,謝謝

以下內(nèi)容,是本人學(xué)習(xí)的筆記和工作中的總結(jié),僅供大家參考,有誤的地方還請(qǐng)指正

一 判定垃圾對(duì)象算法

  • 引用計(jì)數(shù)法
    • 在對(duì)象中添加一個(gè)計(jì)數(shù)器,記錄著指向?qū)ο蟮囊玫膫€(gè)數(shù)
    • 當(dāng)有新的引用指向這個(gè)對(duì)象的時(shí),計(jì)數(shù)器+1,當(dāng)指向?qū)ο蟮囊帽恢胣ull時(shí),計(jì)數(shù)器-1
    • 當(dāng)計(jì)數(shù)器的值為0,那么這個(gè)對(duì)象就是垃圾對(duì)象,就會(huì)被垃圾回收器回收
    • 缺陷:當(dāng)對(duì)象1中有引用指向?qū)ο?,對(duì)象2中有引用指向?qū)ο?,但是再也沒有其他外部引用指向?qū)ο?和對(duì)象2,對(duì)象1、對(duì)象2是垃圾對(duì)象。通過引用計(jì)數(shù)法,對(duì)象1、對(duì)象2計(jì)數(shù)器都為1,不會(huì)被垃圾回收器回收。
    • 不推薦使用
  • 可達(dá)性分析法
    • 該算法的基本思路就是通過GC Roots對(duì)象作為起點(diǎn),從這些節(jié)點(diǎn)開始向下搜索
    • 搜索走過的路徑被稱為引用鏈
    • 當(dāng)一個(gè)對(duì)象,從GC Roots節(jié)點(diǎn)向下搜索,沒有任何一條路徑能夠達(dá)到該對(duì)象,那么這個(gè)對(duì)象就是垃圾對(duì)象
    • 可以做為GC Roots的對(duì)象包括
      • 虛擬機(jī)棧中引用指向的對(duì)象
      • 方法區(qū)中類靜態(tài)屬性所引用的對(duì)象
      • 方法區(qū)中常量所引用的對(duì)象
      • 本地方法棧中引用的對(duì)象

二 垃圾回收算法

  • 標(biāo)記-清除算法
    • 分為標(biāo)記和清楚2步
    • 標(biāo)記:就是通過可達(dá)性分析法將對(duì)象標(biāo)記為垃圾對(duì)象
    • 清除:將垃圾對(duì)象回收
    • 缺點(diǎn):存在效率問題和空間問題
      • 垃圾對(duì)象在堆內(nèi)存中是散亂的,被清除之后,會(huì)導(dǎo)致越來越多不連續(xù)的空間,當(dāng)分配大對(duì)象時(shí),要尋找一片合適的內(nèi)存空間,就會(huì)變得困難
      • 如果找不到合適的內(nèi)存空間存放這個(gè)大對(duì)象,就會(huì)觸發(fā)一次GC,影響性能
  • 復(fù)制算法
    • 年輕代的垃圾收集算法,在年輕代對(duì)象存活率低,復(fù)制算法效率很高
    • 將堆內(nèi)存分成2部分,只在其中一部分中分配內(nèi)存
    • 垃圾回收后,把存活的對(duì)象復(fù)制到另一部分內(nèi)存連續(xù)的空間上
    • 就這樣在2個(gè)內(nèi)存中循環(huán)復(fù)制,這樣解決了 標(biāo)記-清除算法 中的效率問題
    • 缺點(diǎn):由于只在其中一部分中分配內(nèi)存,存在內(nèi)存浪費(fèi)問題
      • 再將內(nèi)存細(xì)分,即可降低內(nèi)存浪費(fèi),詳見Eden、Survivor 0 、Survivor 1、Tenured
  • 標(biāo)記-整理算法
    • 年老代的垃圾收集算法
    • 在年老代對(duì)象存活率高,復(fù)制算法效率低,使用標(biāo)記-整理算法
    • 標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣,
    • 整理:不是直接清除,而是對(duì)內(nèi)存里面的對(duì)象進(jìn)行重新整理,讓所有存活的對(duì)象都向一端移動(dòng),依次排列,那么端邊界另一邊的就都是垃圾對(duì)象了,直接清理掉
    • 標(biāo)記-整理算法唯一的缺點(diǎn)就是效率也不高,不僅要標(biāo)記所有存活對(duì)象,還要整理所有存活對(duì)象的引用地址。從效率上來說,標(biāo)記-整理算法要低于復(fù)制算法。
  • 分代收集算法
    • 根據(jù)不同的內(nèi)存區(qū)選擇不同的算法
    • 在年輕代,選擇復(fù)制算法
    • 在年老代,選擇標(biāo)記-整理算法

三 垃圾回收器

  • Serial
    • 年輕代垃圾收集器,采用復(fù)制算法
    • 串行收集器:如果serial要收集垃圾,必須讓程序其他線程停掉,收集完畢,程序其他線程繼續(xù)執(zhí)行
    • 單線程垃圾收集器:serial單線程收集垃圾
    • 整體效率低
  • Serial Old
    • 它是Serial收集器的年老代版本,與Serial相似,區(qū)別是使用“標(biāo)記-整理”算法
  • Parnew
    • 年輕代垃圾收集器,采用復(fù)制算法
    • 串行收集器:如果parnew要收集垃圾,必須讓程序其他線程停掉,收集完畢,程序其他線程繼續(xù)執(zhí)行
    • 多線程垃圾收集器:parnew多線程收集垃圾
  • Parallel scavenge
    • 與parnew類似,區(qū)別是parallel scavenge能控制吞吐量
    • 吞吐量 = 執(zhí)行用戶代碼的時(shí)間 / (執(zhí)行用戶代碼的時(shí)間 + 垃圾回收所占用的時(shí)間)
      • -xx:MaxGCPauseMillis 垃圾收集器停頓最大時(shí)間,就是垃圾收集線程(多線程)收集垃圾的時(shí)間,是不是設(shè)置越小就越好呢?假設(shè)設(shè)置100ms,垃圾收集器分配的內(nèi)存可能是1G,設(shè)置為1ms,垃圾收集器分配的內(nèi)存可能只有10M,因?yàn)橹挥?0M這么小的內(nèi)存才能在1ms內(nèi)收集完,那么10M內(nèi)存顯然太小了,就會(huì)造成垃圾頻繁回收。原來100ms回收一次的任務(wù),現(xiàn)在如果1ms回收一次,可能要頻繁回收80次,對(duì)比之下性能并沒有多大提升。所以不是設(shè)置的越小越好,應(yīng)該更具實(shí)際情況設(shè)置一個(gè)合理值。
      • -xx:CGTimeRatio 吞吐量大小
    • 適用注重吞吐量的后端服務(wù)
  • Parallel Old
    • 是Parallel Scavenge收集器的年老代版本,與Parallel Scavenge相似,但與Parallel Scavenge不同的是,它使用的是“標(biāo)記-整理算法”
    • 使用方式:-XX:+UseParallelOldGC,打開該收集器后,將使用Parallel Scavenge(年輕代)+Parallel Old(年老代)的組合進(jìn)行GC
  • CMS
    • 年老代、永久代垃圾收集器,采用標(biāo)記-清除算法
    • 并行收集器:垃圾收集線程可以和程序其他線程并發(fā)執(zhí)行
    • 多線程垃圾收集器:CMS多線程收集垃圾
    • 工作過程
      • 初始標(biāo)記:造成程序其他線程停頓。標(biāo)記垃圾對(duì)象
      • 并發(fā)標(biāo)記:與程序線程并發(fā)運(yùn)行。在運(yùn)行期間會(huì)發(fā)生對(duì)象的引用變更等等情況,對(duì)于這些對(duì)象,都是需要進(jìn)行重新標(biāo)記的,否則會(huì)發(fā)生漏標(biāo)的情況。這個(gè)階段因?yàn)槭遣l(fā)的容易導(dǎo)致concurrent mode failure
      • 重新標(biāo)記:會(huì)造成程序其他線程停頓。重新標(biāo)記的內(nèi)存范圍是整個(gè)堆,包含young_gen和old_gen。為什么要掃描新生代呢,因?yàn)閷?duì)于老年代中的對(duì)象,如果被新生代中的對(duì)象引用,那么就會(huì)被視為存活對(duì)象,即使新生代的對(duì)象已經(jīng)不可達(dá)了。所以需要標(biāo)記young_gen和old_gen。
      • 并發(fā)清理:與程序線程并發(fā)運(yùn)行。并發(fā)清理階段用戶線程還在運(yùn)行著,伴隨程序運(yùn)行自然就還會(huì)有新的垃圾不斷產(chǎn)生,這一部分垃圾出現(xiàn)在標(biāo)記過程之后,CMS無法在當(dāng)次收集中處理掉它們,只好留待下一次GC時(shí)再清理掉。這一部分垃圾就稱為“浮動(dòng)垃圾”。
      • 并發(fā)重置:與程序線程并發(fā)運(yùn)行。重新設(shè)置CMS算法內(nèi)部的數(shù)據(jù)結(jié)構(gòu),準(zhǔn)備下一個(gè)CMS生命周期的使用
    • 優(yōu)點(diǎn)
      • 并發(fā)收集
      • 低停頓:只有初始標(biāo)記和重新標(biāo)記會(huì)造成程序其他線程短暫停頓
    • 缺點(diǎn)
      • 占用大量的cpu資源
      • 無法處理浮動(dòng)垃圾
      • 出現(xiàn)Concurrent Mode Failure
      • CMS收集與應(yīng)用線程會(huì)同時(shí)增加對(duì)堆內(nèi)存的占用,也就是說,CMS必須要在老年代堆內(nèi)存用盡之前完成垃圾回收,否則CMS回收失敗,出現(xiàn)Concurrent Mode Failure;
      • 年老代的剩余空間無法滿足新對(duì)象的空間分配,也會(huì)出現(xiàn)這個(gè)錯(cuò)誤
      • 在出現(xiàn)Concurrent Mode Failure時(shí),將觸發(fā)擔(dān)保機(jī)制,Serial Old收集器將會(huì)以STW的方式進(jìn)行一次full gc,從而造成較大停頓時(shí)間,影響性能
  • G1(Garbage First)
    • JDK7增加,成為HotSpot重點(diǎn)發(fā)展的垃圾回收技術(shù),被HotSpot團(tuán)隊(duì)寄予取代CMS的使命
    • 將會(huì)被安排成為JDK9的默認(rèn)垃圾收集器
    • 并行收集器:垃圾收集線程可以和程序其他線程并發(fā)執(zhí)行
    • 多線程垃圾收集器:G1多線程收集垃圾
    • 詳見G1垃圾收集器

四 垃圾回收器作用內(nèi)存區(qū)域以及他們之間的組合關(guān)系

  • 7種不同分代的收集器
    • Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1;
  • 垃圾收集器所屬區(qū)域
    • 年輕代收集器:Serial、ParNew、Parallel Scavenge
    • 年老代收集器:Serial Old、Parallel Old、CMS
    • 整堆收集器:G1
  • 兩個(gè)收集器間有連線,表明它們可以搭配使用
    • Serial/Serial Old
    • Serial/CMS
    • ParNew/Serial Old
    • ParNew/CMS
    • Parallel Scavenge/Serial Old
    • Parallel Scavenge/Parallel Old
    • G1

以上內(nèi)容,是本人學(xué)習(xí)的筆記和工作中的總結(jié),僅供大家參考,有誤的地方還請(qǐng)指正

轉(zhuǎn)載、引用請(qǐng)標(biāo)明出處
http://www.itdecent.cn/p/8ec0ee8ca7ee
本文出自zhh_happig的簡書博客,謝謝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 首先需要解決的問題:哪些對(duì)象已經(jīng)死亡 1.1 引用計(jì)數(shù)算法 引用分析算法是這樣的: 給每一個(gè)對(duì)象添加一個(gè)引用...
    陌城小川閱讀 589評(píng)論 0 0
  • 概念理解新生代收集器Serial收集器ParNew收集器Parallel Scavenge收集器老年代收集器Ser...
    懶癌正患者閱讀 283評(píng)論 0 0
  • 如果說收集算法是內(nèi)存回收的方法論,那么垃圾收集器就是內(nèi)存回收的具體實(shí)現(xiàn)。 Java虛擬機(jī)規(guī)范中對(duì)垃圾收集器應(yīng)該如何...
    夢(mèng)工廠閱讀 17,984評(píng)論 11 64
  • ?若果說收集算法是內(nèi)存會(huì)說的方法論,那么垃圾收集器就是內(nèi)存回收的具體實(shí)現(xiàn)。Java虛擬機(jī)中對(duì)垃圾收集器應(yīng)該如何實(shí)現(xiàn)...
    SunnyMore閱讀 301評(píng)論 0 0
  • 1.概述 在這篇文章中,我主要會(huì)講到以下幾個(gè)內(nèi)容: (1)“垃圾”主要存在于什么位置? (2)什么是“垃圾”? (...
    Ew0828閱讀 437評(píng)論 0 1

友情鏈接更多精彩內(nèi)容