JVM:GC(垃圾回收算法)

垃圾回收機制:

什么時候:
什么時候開啟垃圾回收(觸發(fā)GC的條件),GC觸發(fā)的條件有兩種:①抬虽、程序調(diào)用System.gc時可以觸發(fā);②属桦、系統(tǒng)自身判斷GC的依據(jù):根據(jù)Eden區(qū)和From Space區(qū)的內(nèi)存大小來決定匠题。當(dāng)內(nèi)存大小不足時缔赠,則會啟動GC線程并停止應(yīng)用線程。

對什么東西:
GC操作的對象分為:通過可達(dá)性分析法無法搜索到的對象和可以搜索到的對象褂微,對于搜索不到的對象進(jìn)行標(biāo)記

做了什么:
對于可以搜索到的對象進(jìn)行復(fù)制操作功蜓,對于搜索不到的對象,調(diào)用finalize()方法進(jìn)行釋放宠蚂。

常見的垃圾回收算法:

  • 引用計數(shù):

    • 每個對象有一個引用計數(shù)屬性式撼,新增一個引用時計數(shù)加1,引用釋放時計數(shù)減1肥矢,計數(shù)為0時可用回收端衰。此方法簡單,無法解決對象相互循環(huán)引用的問題甘改,且每次對對象復(fù)制時均要維護(hù)引用計數(shù)器旅东,且計數(shù)器本身也有一定的消耗。\color{red}{JVM的實現(xiàn)一般不采用這種方式}

復(fù)制算法:

堆內(nèi)存.png

堆內(nèi)存:

  • 新生代:新生代劃分為Eden(伊甸園)與SurvivorFrom與SurvivorTo
  • 老年代:老年代的空間里只有老年代
    • 1十艾、首先抵代,當(dāng)Eden區(qū)滿的時候回觸發(fā)第一次GC,把還活著的對象拷貝到SurvivorFrom區(qū)忘嫉,當(dāng)Eden區(qū)再次觸發(fā)GC的時候會掃描Eden區(qū)和From區(qū)域荤牍,對這兩個區(qū)域進(jìn)行垃圾回收案腺,經(jīng)過這次回收后還存活著的對象,則直接復(fù)制到To區(qū)域(如果有對象的年齡已經(jīng)達(dá)到了老年的標(biāo)準(zhǔn)康吵,則賦值到老年代區(qū))劈榨,同時把這些對象的年齡 + 1
    • 2、然后晦嵌,情況Eden和SurvivoFrom中的對象同辣,也即復(fù)制之后有交換,誰空誰是To
    • 3惭载、SurvivorTo和SurvivorFrom互換
      最后旱函,SUrvivoTo和SurvivorFrom互換,原SurvivorTo成為下一次GC時的SurvivorFrom區(qū)描滔。部分對象會在From和To區(qū)域中復(fù)制來復(fù)制去棒妨,如此交換15次(由JVM參數(shù)MaxTenuringThreshold決定,這個參數(shù)默認(rèn)是15)含长,最終如果還是存活券腔,就存入老年代
      優(yōu)點:
      在存活對象不多的情況下,性能高拘泞,能解決內(nèi)存碎片和java垃圾回收算法之-標(biāo)記清除中導(dǎo)致的引用更新問題颅眶。
      缺點:
      會造成一部分的內(nèi)存浪費。不過可以根據(jù)實際情況田弥,將內(nèi)存塊大小比例適當(dāng)調(diào)整涛酗;
      如果存活對象的數(shù)量比較大,coping的性能會變得很差
  • 標(biāo)記清除算法

    標(biāo)記清除.png

    標(biāo)記清除算法分為兩個階段:標(biāo)記和清除偷厦。
    它的做法是當(dāng)堆中的有效內(nèi)存空間(available memory)被耗盡的時候商叹,就會讓整個程序stop然后進(jìn)行標(biāo)記再清除
    標(biāo)記:標(biāo)記的過程其實就是,遍歷所有的GC Roots只泼,然后將所有的GC Roots可達(dá)的對象標(biāo)記為存活的對象剖笙。
    清除:清除的過程將遍歷堆中所有的對象中沒有標(biāo)記的對象全部清除掉
    缺點:
    1、它的缺點就是效率比較低(遞歸與全堆對象遍歷)请唱,而且在進(jìn)行GC的時候弥咪,需要停止應(yīng)用程序。
    2十绑、這種方式清理出來的空閑內(nèi)存是不連續(xù)的聚至。我們的死亡對象都是隨機的出現(xiàn)在內(nèi)存的各個角落,把它們都清除之后本橙,內(nèi)存的布局自然會亂七八糟扳躬,為了應(yīng)付這一點,JVM就不得不維持一個內(nèi)存的空閑列表,這又是一個開銷贷币。而且在分配數(shù)組對象的击胜,尋找連續(xù)的內(nèi)存不好找

  • 標(biāo)記整理
    分為標(biāo)記和整理兩個階段:首先標(biāo)記出所有需要回收的對象,讓所有存活的對象都向一端移動役纹,然后直接清理掉邊界意外的內(nèi)存偶摔。
    優(yōu)點:不會產(chǎn)生空間碎片,但是整理會需要一點時間
    地方:適合老年代進(jìn)行垃圾收集促脉,parallel Old(針對parallel scanvange gc的) gc和Serial old收集器就是采用該算法進(jìn)行回收的啰挪。

  • 分代收集算法
    目前商用虛擬機都使用“分代收集算法”,所謂分代就是根據(jù)對象的生命周期把內(nèi)存分為幾塊嘲叔,一般把Java堆中分為新生代和老年代,這樣就可以根據(jù)對象的“年齡”選擇合適的垃圾回收算法抽活。

    • 新生代:“朝生夕死”硫戈,存活率低,使用復(fù)制算法下硕。
    • 老年代:存活率較高丁逝,使用“標(biāo)記-清除”算法或者“標(biāo)記-整理”算法。

垃圾收集器

如果說收集算法是內(nèi)存回收的方法論梭姓,垃圾收集器就是內(nèi)存回收的具體實現(xiàn)

Serial收集器
串行收集器是最古老霜幼,最穩(wěn)定以及效率高的收集器,可能會產(chǎn)生較長的停頓誉尖,只是用一個線程去回收罪既。新生代、老年代使用串行回收铡恕;新生代復(fù)制算法琢感、老年代標(biāo)記 - 壓縮;垃圾收集的過程中會Stop The World(服務(wù)暫停)
參數(shù)控制: -XX:+UseSerialGC 串行收集器

image

  • ParNew 收集器 ParNew收集器其實就是Serial收集器的多線程版本探熔。新生代并行驹针,老年代串行;新生代復(fù)制算法诀艰、老年代標(biāo)記-壓縮
    參數(shù)控制:
    -XX:+UseParNewGC ParNew收集器
    -XX:ParallelGCThreads 限制線程數(shù)量


    image

Parallel收集器

Parallel Scavenge收集器類似ParNew收集器,Parallel收集器更關(guān)注系統(tǒng)的吞吐量∷酪Γ可以通過參數(shù)來打開自適應(yīng)調(diào)節(jié)策略爽丹,虛擬機會根據(jù)當(dāng)前系統(tǒng)的運行情況收集性能監(jiān)控信息,動態(tài)調(diào)整這些參數(shù)以提供最合適的停頓時間或最大的吞吐量绿满;也可以通過參數(shù)控制GC的時間不大于多少毫秒或者比例撤防;新生代復(fù)制算法、老年代標(biāo)記-壓縮
參數(shù)控制: -XX:+UseParallelGC 使用Parallel收集器+ 老年代串行

Parallel Old 收集器
Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程和“標(biāo)記-整理”算法寄月。這個收集器是在JDK 1.6中才開始提供
參數(shù)控制: -XX:+UseParallelOldGC 使用Parallel收集器+ 老年代并行

CMS收集器
CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標(biāo)的收集器辜膝。目前很大一部分的Java應(yīng)用都集中在互聯(lián)網(wǎng)站或B/S系統(tǒng)的服務(wù)端上,這類應(yīng)用尤其重視服務(wù)的響應(yīng)速度漾肮,希望系統(tǒng)停頓時間最短厂抖,以給用戶帶來較好的體驗。
從名字(包含“Mark Sweep”)上就可以看出CMS收集器是基于“標(biāo)記-清除”算法實現(xiàn)的克懊,它的運作過程相對于前面幾種收集器來說要更復(fù)雜一些忱辅,整個過程分為4個步驟,包括:

  • 初始標(biāo)記(CMS initial mark)

  • 并發(fā)標(biāo)記(CMS concurrent mark)

  • 重新標(biāo)記(CMS remark)

  • 并發(fā)清除(CMS concurrent sweep)

其中初始標(biāo)記谭溉、重新標(biāo)記這兩個步驟仍然需要“Stop The World”墙懂。初始標(biāo)記僅僅只是標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對象,速度很快扮念,并發(fā)標(biāo)記階段就是進(jìn)行GC Roots Tracing的過程损搬,而重新標(biāo)記階段則是為了修正并發(fā)標(biāo)記期間,因用戶程序繼續(xù)運作而導(dǎo)致標(biāo)記產(chǎn)生變動的那一部分對象的標(biāo)記記錄柜与,這個階段的停頓時間一般會比初始標(biāo)記階段稍長一些巧勤,但遠(yuǎn)比并發(fā)標(biāo)記的時間短。
由于整個過程中耗時最長的并發(fā)標(biāo)記和并發(fā)清除過程中弄匕,收集器線程都可以與用戶線程一起工作颅悉,所以總體上來說,CMS收集器的內(nèi)存回收過程是與用戶線程一起并發(fā)地執(zhí)行迁匠。老年代收集器(新生代使用ParNew)
優(yōu)點: 并發(fā)收集剩瓶、低停頓
缺點: 產(chǎn)生大量空間碎片、并發(fā)階段會降低吞吐量
參數(shù)控制:
-XX:+UseConcMarkSweepGC 使用CMS收集器
-XX:+ UseCMSCompactAtFullCollection Full GC后城丧,進(jìn)行一次碎片整理儒搭;整理過程是獨占的,會引起停頓時間變長
-XX:+CMSFullGCsBeforeCompaction 設(shè)置進(jìn)行幾次Full GC后芙贫,進(jìn)行一次碎片整理
-XX:ParallelCMSThreads 設(shè)定CMS的線程數(shù)量(一般情況約等于可用CPU數(shù)量)


image

G1收集器

GcRoot

所謂"GC roots" 或者說tracing GC的"根集合"就是一組必須活躍的引用搂鲫。
基本思路就是通過一系列名為"GC Roots"的對象作為起始點,從這個被稱為GC Roots的對象開始向下搜索磺平,如果一個對象到GC Roots沒有任何引用鏈相連時魂仍,則說明此對象不可用。也即給定一個集合的引用作為根出發(fā)拣挪,通過引用關(guān)系遍歷對象圖擦酌,能被遍歷到的(可到達(dá)的)對象就被判定為存活;沒有被遍歷到的就自然被判定為死亡

哪些可以作為GC Roots的對象:
虛擬機棧(棧幀中的局部變量區(qū)菠劝,也叫做局部變量表)中引用的對象
方法區(qū)中的類靜態(tài)屬性引用的對象赊舶。
方法區(qū)中常量引用的對象
本地方法棧中JNI(Native方法)引用的對象

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子笼平,更是在濱河造成了極大的恐慌园骆,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寓调,死亡現(xiàn)場離奇詭異锌唾,居然都是意外死亡,警方通過查閱死者的電腦和手機夺英,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進(jìn)店門晌涕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人痛悯,你說我怎么就攤上這事余黎。” “怎么了载萌?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵惧财,是天一觀的道長。 經(jīng)常有香客問我炒考,道長,這世上最難降的妖魔是什么霎迫? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任斋枢,我火速辦了婚禮,結(jié)果婚禮上知给,老公的妹妹穿的比我還像新娘瓤帚。我一直安慰自己,他們只是感情好涩赢,可當(dāng)我...
    茶點故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布戈次。 她就那樣靜靜地躺著,像睡著了一般筒扒。 火紅的嫁衣襯著肌膚如雪怯邪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天花墩,我揣著相機與錄音悬秉,去河邊找鬼。 笑死冰蘑,一個胖子當(dāng)著我的面吹牛和泌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播祠肥,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼武氓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起县恕,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤东羹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后弱睦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體百姓,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年况木,在試婚紗的時候發(fā)現(xiàn)自己被綠了垒拢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡火惊,死狀恐怖求类,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情屹耐,我是刑警寧澤尸疆,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站惶岭,受9級特大地震影響寿弱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜按灶,卻給世界環(huán)境...
    茶點故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一症革、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鸯旁,春花似錦噪矛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至韭赘,卻和暖如春缩滨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背泉瞻。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工楷怒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瓦灶。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓鸠删,卻偏偏與公主長得像,于是被迫代替她去往敵國和親贼陶。 傳聞我的和親對象是個殘疾皇子刃泡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,666評論 2 350