JVM垃圾收集器(一)

說到GC,相信大家都不陌生妆艘,對(duì)于Java開發(fā)的同學(xué)來說,之所以能毫無顧忌的申請(qǐng)新的空間幌陕,不用像c/c++那樣malloc/new之后,還需要free/delete搏熄,就是靠它了逗物。
??在正式了解GC之前,我們先想一想翎卓,我們都想了解它什么?可能會(huì)比較好奇一下幾個(gè)方面:

  • GC回收都回收那些內(nèi)存坯门?
  • GC什么時(shí)候會(huì)回收內(nèi)存?判定可以回收的條件是怎樣的古戴?
  • GC是怎樣回收的矩肩?
    帶著以上幾個(gè)問題,我們往下走:

一叉袍、回收哪些內(nèi)存?

經(jīng)過之前JVM內(nèi)存結(jié)構(gòu)的講解喳逛,想必大家已經(jīng)了解到了:jvm運(yùn)行時(shí)數(shù)據(jù)區(qū)棵里,大的來說分2部分——線程公有和線程私有姐呐。私有部分:程序計(jì)數(shù)器(PC)曙砂、jvm棧、本地方法棧麦轰,公有部分:方法區(qū)或稱為perm區(qū)砖织、java堆侧纯。私有部分是線程私有的,隨線程生而生眶熬,滅而滅块请,所以這些地方的內(nèi)存區(qū)域,會(huì)隨著方法的結(jié)束或者線程的結(jié)束而被回收墩新,不需要我們關(guān)心;但是公有的部分就不一樣了绵疲,A線程結(jié)束了臣疑,很可能這個(gè)變量,B線程還在使用讯沈,這時(shí)候就不能回收,所以GC的回收內(nèi)存區(qū)域就是java堆和方法區(qū)缺狠。

二、什么時(shí)候回收內(nèi)存蝴乔?

既然叫GC(Garbage Collection)——垃圾收集器驮樊,那就是說GC只是收集垃圾內(nèi)存片酝,何為垃圾內(nèi)存挖腰?和平時(shí)生活一樣,我們不會(huì)再使用的就是垃圾审轮,就需要回收辽俗。所以GC回收也就是不會(huì)再被使用了的對(duì)象實(shí)例

那么問題來了崖飘,如何能判定對(duì)象是否還使用了?

2.1引用計(jì)數(shù)算法

給對(duì)象添加一個(gè)引用計(jì)數(shù)器吊圾,每當(dāng)有一個(gè)地方引用它時(shí)翰蠢,計(jì)數(shù)器就加1;當(dāng)引用失效的時(shí)候梁沧,計(jì)數(shù)器減1;任何時(shí)候計(jì)數(shù)器為0的對(duì)象就是不可能再被使用的對(duì)象埃碱。

優(yōu)點(diǎn):判定高效酥泞。
缺點(diǎn):無法解決循環(huán)引用的問題,循環(huán)引用的對(duì)象的計(jì)數(shù)器都是1芝囤,所以永遠(yuǎn)無法被回收。

如下例:

public class ReferenceCountingGC {
    public Object instance = null;
    private static final int _1MB = 1024 * 1024;
    private byte[] bigSize = new byte[2*_1MB];
    public static void main(String[] args) {
        //1.創(chuàng)建2個(gè)實(shí)例
        ReferenceCountingGC objcA = new ReferenceCountingGC();
        ReferenceCountingGC objcB = new ReferenceCountingGC();
        //2.賦值
        objcA.instance = objcB;
        objcB.instance = objcA;
        //3.對(duì)象引用置為空
        objcA = null;
        objcB = null;
    }
}

以上過程的內(nèi)存圖如下:
??上面步驟一和步驟二執(zhí)行之后羡藐,對(duì)應(yīng)的內(nèi)存結(jié)構(gòu)圖悯许,如下圖一所示。其中對(duì)象A和對(duì)象B的引用值都是2瘩扼。

圖一.png

??步驟三:將A和B的引用都置為空,得到的結(jié)構(gòu)圖如下所示集绰。

圖二.png

??我們可以看到線程結(jié)束,但是對(duì)象A和對(duì)象B是不會(huì)被回收的罕袋。

2.2可達(dá)性分析算法

這個(gè)算法的基本思路就是通過一系列的稱謂“GC Roots"的對(duì)象作為起始點(diǎn)碍岔,從這些節(jié)點(diǎn)開始向下搜索,搜索所有走過的路徑為引用鏈蔼啦,當(dāng)一個(gè)對(duì)象到GC Roots沒有任何引用鏈項(xiàng)鏈時(shí),則證明此對(duì)象時(shí)不可用的。 如下圖:

GC-ROOT.png

可作為GC Roots的對(duì)象包括下面幾種:

  1. 虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象
  2. 方法區(qū)中類靜態(tài)屬性引用的對(duì)象
  3. 方法區(qū)中常量引用的對(duì)象
  4. 本地方法棧中JNI(即一般說的Native方法)引用的對(duì)象
圖三.png

??從上圖中可以看到猛计,對(duì)于對(duì)象A和對(duì)象B來說爆捞,他們是屬于不可達(dá)的對(duì)象,在GC的時(shí)候是會(huì)被回收的煮甥,而對(duì)于其他的對(duì)象來說,都還在被使用卖局,所以不會(huì)被回收。

2.3 java中的引用類型

從JDK1.2之后砚偶,Java對(duì)引用的概念進(jìn)行了擴(kuò)充洒闸,將引用分為強(qiáng)引用(Strong Reference)、軟引用(Soft Reference)丘逸、弱引用(Weak Reference)、虛引用(Phantom Reference)仲锄,這四種引用的強(qiáng)度一次逐漸減弱

  1. 強(qiáng)引用就是指在程序代碼之中普遍存在的,類似 “Object obj = new Object()” 這類的引用昼窗,只要強(qiáng)引用還存在,垃圾回收器永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象澄惊。
  2. 軟引用是用來描述一些還有用但并非需要的對(duì)象,對(duì)于軟引用關(guān)聯(lián)著的對(duì)象掸驱,在系統(tǒng)將要發(fā)生內(nèi)存異常之前,將會(huì)把這些對(duì)象列進(jìn)回收范圍之中進(jìn)行第二次回收毕贼,如果這次回收還沒有足夠的內(nèi)存,才會(huì)拋出內(nèi)存異常
  3. 弱引用也是用來描述非必需對(duì)象的陶贼,但是它的強(qiáng)度比軟引用更弱一些待秃,被弱引用關(guān)聯(lián)的對(duì)象只能生存到下一次垃圾收集發(fā)生之前,當(dāng)垃圾收集器工作時(shí)章郁,無論當(dāng)前內(nèi)存釋放足夠,都會(huì)回收掉只被弱引用關(guān)聯(lián)的對(duì)象
  4. 虛引用也稱為幽靈引用或者幻影引用聊替,它是最弱的一種引用關(guān)系,一個(gè)對(duì)象是否有虛引用的存在惹悄,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響肩钠,也無法通過虛引用來取得一個(gè)對(duì)象實(shí)例,對(duì)一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個(gè)對(duì)象被收集器回收時(shí)收到一個(gè)系統(tǒng)通知

對(duì)于方法區(qū)的回收問題:
??方法區(qū)的回收主要回收:廢棄常量和無用的類爷速。
無用的類的判定:
1.該類所有的實(shí)例都已經(jīng)被回收;
2.加載該類的ClassLoader已經(jīng)被回收惫东;
3.改類對(duì)應(yīng)的java.lang.Class對(duì)象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法颓遏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末滞时,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坪稽,更是在濱河造成了極大的恐慌,老刑警劉巖黍判,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篙梢,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡渤滞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門陶舞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趴腋,“玉大人优炬,你說我怎么就攤上這事〈阑ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵葵硕,是天一觀的道長贯吓。 經(jīng)常有香客問我,道長悄谐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任们陆,我火速辦了婚禮,結(jié)果婚禮上杂腰,老公的妹妹穿的比我還像新娘。我一直安慰自己喂很,他們只是感情好雾袱,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著毒坛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪煎殷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,785評(píng)論 1 314
  • 那天豪直,我揣著相機(jī)與錄音珠移,去河邊找鬼。 笑死暇韧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的懈玻。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼涂乌,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼英岭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起历涝,我...
    開封第一講書人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荧库,沒想到半個(gè)月后堰塌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體分衫,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚪战,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了邀桑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贼急,死狀恐怖捏萍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情令杈,我是刑警寧澤,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布掉丽,位于F島的核電站,受9級(jí)特大地震影響异雁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜片迅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一皆辽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧驱闷,春花似錦、人聲如沸空另。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至析恢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間映挂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來泰國打工帽撑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人亏拉。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓寸癌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蒸苇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

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

  • 1.什么是垃圾回收味咳? 垃圾回收(Garbage Collection)是Java虛擬機(jī)(JVM)垃圾回收器提供...
    簡欲明心閱讀 89,587評(píng)論 17 311
  • 通過這篇文章你能知道的問題: 1.如何判斷對(duì)象是活著還是死去檬嘀? 2.在Java語言中,可作為GCRoots的對(duì)象有...
    beneke閱讀 1,355評(píng)論 0 1
  • JVM架構(gòu) 當(dāng)一個(gè)程序啟動(dòng)之前掂铐,它的class會(huì)被類裝載器裝入方法區(qū)(Permanent區(qū)),執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,673評(píng)論 0 7
  • 作者:一字馬胡 轉(zhuǎn)載標(biāo)志 【2017-11-12】 更新日志 日期更新內(nèi)容備注 2017-11-12新建文章初版 ...
    beneke閱讀 2,211評(píng)論 0 7
  • 原文閱讀 前言 這段時(shí)間懈怠了,罪過衷掷! 最近看到有同事也開始用上了微信公眾號(hào)寫博客了辱姨,挺好的~給他們點(diǎn)贊雨涛,這博客我...
    碼農(nóng)戲碼閱讀 5,994評(píng)論 2 31