Java GC 必知必會

1. Java 如何標(biāo)識垃圾

常用的標(biāo)識算法主要是兩類,一是計數(shù)器引用法杰刽,二是可達(dá)性分析(根搜索算法)缀匕。

  • 計數(shù)器引用法

  • 可達(dá)性分析
    基本思路:

    • 已根對象集合為起點(diǎn)强窖,按照從上之下的方式搜索被根對象集合所連接的目標(biāo)對象是否可達(dá)泪姨。
    • 使用可達(dá)性分析算法后游沿,內(nèi)存中的存活對象都會被根對象集合直接或間接連接著,搜索所走過的路徑成為引用鏈.
image.png

2. GC ROOTS 包含哪些肮砾?

  • 虛擬機(jī)棧中引用的對象
    》 比如各個線程中被調(diào)用的方法中使用的參數(shù)诀黍,局部變量
  • 本地方法棧引用的對象
  • 方法區(qū)中類靜態(tài)屬性引用的對象
    》 java類的引用類型靜態(tài)變量
  • 方法區(qū)中常量引用的對象
    》 字符串常量池里面的應(yīng)用
  • 被synchronized持有的對象
  • java虛擬機(jī)內(nèi)部的引用
  • 反映java虛擬機(jī)內(nèi)部情況的JMXBean,JVMTI中的回調(diào)唇敞,本地代碼緩存等蔗草。

特殊情況:
有對象“臨時性”的加入咒彤,共同構(gòu)成完成GC Roots集合疆柔。比如分代收集和局部回收(Partial GC)

image.png
image.png

3. 為什么會產(chǎn)生STW

如果要使用可達(dá)性分析算法來判斷內(nèi)存是否可回收,那么分析工作必須在一個能保障一致性的快照中進(jìn)行镶柱。這點(diǎn)不滿足的話旷档,那分析的結(jié)果準(zhǔn)確性也就無法保障。

所以就會產(chǎn)生了Stop The World的一個重要原因歇拆。

4. 對象的finalization機(jī)制

  • 用于開發(fā)人員對對象被銷毀前的自定義邏輯處理鞋屈。通常用于對象被回收時范咨,進(jìn)行資源釋放和清理的工作。

  • 關(guān)閉文件流厂庇,關(guān)閉數(shù)據(jù)庫連接等渠啊。

finalization為什么不要手工調(diào)用

  • 有可能導(dǎo)致對象復(fù)活
  • finalization的執(zhí)行時間點(diǎn)不確定。在極端情況下权旷,如果不發(fā)生GC替蛉,那么finalization將永遠(yuǎn)不會被執(zhí)行。

finalization 導(dǎo)致對象復(fù)活的情況
在虛擬機(jī)定義中拄氯,對象存在三種狀態(tài)
1. 可觸及的:從GC ROOT可達(dá)
2. 可復(fù)活的:對象多有的引用都被釋放了躲查,但是對象可能在finalization() 被復(fù)活。
3. 不可觸及的:對象的finalization()被調(diào)用译柏,并且沒有復(fù)活镣煮。那么就會就如不可觸及的狀態(tài)。不可觸及的對象就一定會被回收鄙麦。因?yàn)?code>finalization只會被調(diào)用一次典唇。

5. 如何判斷一個對象是否可以被回收?

判斷一個對象能否被收回黔衡,至少要經(jīng)歷兩次判斷蚓聘。

  1. 如果objA到GC Roots沒有引用鏈,則進(jìn)行第一次標(biāo)記
  2. 判斷對象是否有必要執(zhí)行finalization()方法
    • 如果沒有重寫finalization()或者finalization()已經(jīng)被執(zhí)行過了盟劫,則被判斷為不可觸及的夜牡。
    • 如果對象重寫了finalization()方法,且還未被執(zhí)行過侣签。那么objA會被插入到F-Queue隊(duì)列中塘装,由一個虛擬機(jī)自動創(chuàng)建的低優(yōu)先級的finalizer線程觸發(fā)其finalization()。
  • finalization()是對象逃脫死亡的最后機(jī)會影所。稍后GC會對F-Queue 隊(duì)列中的對象進(jìn)行二次標(biāo)記蹦肴。 如果objA在此時與引用鏈上的任何一個對象建立了聯(lián)系,那么objA會被移出“即將回收”集合猴娩。

6. JVM GC 清除階段的算法

6.1 標(biāo)記-清除算法(Mark-Sweep)

image.png
image.png
  • 優(yōu)點(diǎn): 比較容易理解
  • 缺點(diǎn)
  1. 效率不算高
  2. 會產(chǎn)生內(nèi)存碎片阴幌,還需要額外的空間維護(hù)一個空閑列表。

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

image.png
image.png

優(yōu)點(diǎn):

  • 保證空間連續(xù)卷中,不會出現(xiàn)碎片問題
  • 實(shí)現(xiàn)相對簡單矛双,運(yùn)行高效

缺點(diǎn):

  • 需要兩倍的空間
  • 當(dāng)系統(tǒng)存活的對象數(shù)量很多時,性能較低蟆豫。(所以只能用于新生代)

6.3 標(biāo)記-壓縮算法(Mark-Compact)

image.png
image.png

優(yōu)點(diǎn)

  • 沒有內(nèi)存碎片
  • 減少了內(nèi)存的浪費(fèi)

缺點(diǎn)

  • 從效率來說议忽,標(biāo)記整理算法要低于復(fù)制算法
  • 移動對象的同時,如果對象被其他對象引用十减,則還需調(diào)整引用地址栈幸。
  • STW的時間相比于其他要長一些愤估,因?yàn)樯婕暗綄ο蟮囊苿雍鸵酶隆?/li>
image.png

7. GC 分帶收集算法&增量收集算法&分區(qū)算法

分帶收集算法

image.png

增量收集算法

image.png

分區(qū)算法

image.png

8. System.gc()和Runtime.getRuntime().gc()的理解

  • 默認(rèn)情況下固歪,通過System.gc()和Runtime.getRuntime().gc()顯示調(diào)用時仇轻,會觸發(fā)Full GC,同時對老年代和新生代進(jìn)行回收募疮,嘗試釋放對象占用的內(nèi)存芍锚。
  • System.gc()無法保證對垃圾回收器的調(diào)用
  • Sysmte.gc()等同與Runtime.getRuntime().gc()

gc與slot的關(guān)系

image.png

在這個案例中 buffer所占用空間不會被回收震捣,因?yàn)閟lot=1的位置還是被buffer這個變量所占用。在gc時闹炉,屬于GC Root可達(dá)的情況蒿赢。

9. 程序的并行與并發(fā)

image.png

垃圾回收器的并行與并發(fā)

image.png

image.png

10. GC 中的安全點(diǎn)與安全區(qū)域的說明

  • Safepoint


    image.png

如何讓線程在安全點(diǎn)中斷:


image.png
  • SafeRegion


    image.png

實(shí)際執(zhí)行流程

image.png

11. java引用:強(qiáng),軟渣触,弱羡棵,虛

  • 強(qiáng)引用:不回收

    1. 強(qiáng)引用的對象的GC Root可達(dá)的,所以垃圾回收器永遠(yuǎn)不會回收嗅钻。
    2. 強(qiáng)引用也是造成內(nèi)存泄漏的主要原因之一皂冰。
  • SoftReference 軟引用:內(nèi)存不足時及回收

    1. 用于描述一下有用但是非必須的對象。只被弱引用關(guān)聯(lián)者的對象养篓,在系統(tǒng)將要發(fā)生內(nèi)存溢出前秃流,會把這些對象列入回收范圍內(nèi)進(jìn)行二次回收。如果這次回收還是沒有足夠的內(nèi)存柳弄,才會報出OOM舶胀。
    2. 一般使用場景是:如mybaits中的本地緩存
  • WeakReference 弱引用:發(fā)現(xiàn)即回收

  1. 只被弱引用關(guān)聯(lián)的對象,只能存活到下一次GC發(fā)生為止碧注。
  2. 常用的實(shí)現(xiàn)類是WeekHashMap嚣伐,在Tomcat中作為了一個LRU的cache實(shí)現(xiàn)。

軟引用和弱引用的區(qū)別點(diǎn):


image.png
  • PhantomReference 虛引用:
    image.png
  1. 使用場景:追蹤垃圾回收
  • ** 終結(jié)器引用:**
    對象finalization的底層實(shí)現(xiàn)


    image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末萍丐,一起剝皮案震驚了整個濱河市轩端,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逝变,老刑警劉巖基茵,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異壳影,居然都是意外死亡拱层,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門态贤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舱呻,“玉大人醋火,你說我怎么就攤上這事悠汽∠渎溃” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵柿冲,是天一觀的道長茬高。 經(jīng)常有香客問我,道長假抄,這世上最難降的妖魔是什么怎栽? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮宿饱,結(jié)果婚禮上熏瞄,老公的妹妹穿的比我還像新娘。我一直安慰自己谬以,他們只是感情好强饮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著为黎,像睡著了一般邮丰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上铭乾,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天剪廉,我揣著相機(jī)與錄音,去河邊找鬼炕檩。 笑死斗蒋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的笛质。 我是一名探鬼主播吹泡,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼经瓷!你這毒婦竟也來了爆哑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤舆吮,失蹤者是張志新(化名)和其女友劉穎揭朝,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體色冀,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡潭袱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了锋恬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屯换。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出彤悔,到底是詐尸還是另有隱情嘉抓,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布晕窑,位于F島的核電站抑片,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏杨赤。R本人自食惡果不足惜敞斋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疾牲。 院中可真熱鬧植捎,春花似錦、人聲如沸阳柔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盔沫。三九已至医咨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間架诞,已是汗流浹背拟淮。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谴忧,地道東北人很泊。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像沾谓,于是被迫代替她去往敵國和親委造。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

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