Android必學(xué)基礎(chǔ)知識(shí)之垃圾回收

前言

?Java堆和方法區(qū)兩個(gè)區(qū)域有明顯的不確定性,因?yàn)橐粋€(gè)接口的多個(gè)實(shí)現(xiàn)類需要的內(nèi)存可能不一樣婆殿,一個(gè)方法所執(zhí)行的不同條件分支所需的內(nèi)存也可能不一樣埋涧,只有處于運(yùn)行期間垄潮,我們才能知道創(chuàng)建哪些對(duì)象,創(chuàng)建多少個(gè)對(duì)象章咧,這部分內(nèi)存的分配和回收是動(dòng)態(tài)的倦西,垃圾回收器所關(guān)注的正是這部分內(nèi)存該如何管理。


1 引用計(jì)數(shù)法

?Python赁严、微軟COM技術(shù)扰柠、使用ActionScript 3的FlashPlayer使用引用計(jì)數(shù)法進(jìn)行管理內(nèi)存。

1.1 定義

?在對(duì)象中添加一個(gè)引用計(jì)數(shù)器疼约,沒(méi)一個(gè)地方引用它時(shí)卤档,計(jì)數(shù)器值就加一;當(dāng)引用失效時(shí)程剥,計(jì)數(shù)器值就減一劝枣;任何時(shí)刻計(jì)時(shí)器為零的對(duì)象就是不可能再被使用的

1.2 為什么JVM不使用引用計(jì)數(shù)法管理內(nèi)存?

?因?yàn)橐糜?jì)數(shù)法有很多特殊情況需要考慮舔腾,必須要配合大量的額外處理才能保證正確工作溪胶,例如單純的引用計(jì)數(shù)就很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題


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

?Java琢唾、C#使用可達(dá)性分析來(lái)判定對(duì)象是存活载荔。

2.1 定義

?以"GC Roots"的根對(duì)象作為起始節(jié)點(diǎn)集,從這些節(jié)點(diǎn)開始采桃,根據(jù)引用關(guān)系向下搜索懒熙,搜索過(guò)程中所走過(guò)的路徑為“引用鏈”,如果某個(gè)對(duì)象到"GC Roots"間沒(méi)有任何引用鏈相連普办,就可以稱為對(duì)象不可達(dá)工扎,證明此對(duì)象是并不可能再被使用的

2.2 GC Roots對(duì)象

?在Java技術(shù)體系里面衔蹲,固定可作為GC Roots的對(duì)象包括以下幾種:

  • 在虛擬機(jī)棧中的本地變量表引用的對(duì)象肢娘,例如:線程被調(diào)用的方法堆棧中使用到的參數(shù)、局部變量舆驶、臨時(shí)變量等橱健。
  • 在方法區(qū)中靜態(tài)屬性引用的對(duì)象,例如:Java類的引用類型靜態(tài)變量沙廉。
  • 在方法去中引用的對(duì)象拘荡,例如:字符常量池里的引用。
  • 在本地方法棧中JNI引用的對(duì)象撬陵。
  • Java虛擬機(jī)內(nèi)部的引用珊皿,如基本數(shù)據(jù)類型對(duì)應(yīng)的Class對(duì)象,一些常駐的異常對(duì)象等巨税,還有系統(tǒng)類加載器蟋定。
  • 所有被同步鎖(Syschronized關(guān)鍵字)持有的對(duì)象。
  • 反映Java虛擬機(jī)內(nèi)部情況的JMXBean草添、JVMTI中注冊(cè)的回調(diào)驶兜、本地代碼緩存等。
    ?G1远寸、ZGC等垃圾回收器還實(shí)現(xiàn)了局部回收促王,它們?cè)趯?shí)現(xiàn)上也做了跟中優(yōu)化處理。

3 引用

?無(wú)論是引用計(jì)數(shù)法還是可行性分析算法判定對(duì)象是否存活都和"引用"離不開關(guān)系而晒,引用根據(jù)回收時(shí)機(jī)可以分為強(qiáng)引用(Strongly Refrence)蝇狼、軟引用(Soft Refrence)、弱引用(Weak Refrence)倡怎、虛引用(Phantom Refrence)

3.1 強(qiáng)引用(Strongly Refrence)

?程序代碼中普遍存在的引用賦值迅耘,即類似Object obj = new Object()贱枣,只要強(qiáng)引用關(guān)系還存在,垃圾回收器就永遠(yuǎn)不會(huì)回收被引用的對(duì)象颤专。

3.2 軟引用(Soft Refrence)

?內(nèi)存不足時(shí)被回收纽哥,如果回收之后內(nèi)存還時(shí)不夠用就拋出OOM。

3.3 弱引用(Weak Refrence)

?下一次GC時(shí)被回收栖秕。

3.4 虛引用(Phantom Refrence)

?一個(gè)對(duì)象是否有虛引用存在春塌,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響,也無(wú)法通過(guò)虛引用來(lái)取得一個(gè)對(duì)象實(shí)例簇捍。為一個(gè)對(duì)象設(shè)置虛引用的目的只是為了能在這個(gè)對(duì)象被垃圾回收器回收時(shí)都到一個(gè)系統(tǒng)通知只壳。


4 垃圾收集算法

?從如何判定對(duì)象消亡的角度出發(fā),垃圾收集算法可以劃分為“引用計(jì)數(shù)式垃圾收集”和“追蹤式垃圾收集”暑塑,JVM所有垃圾回收算法均屬于“追蹤式垃圾收集”吼句。

4.1 分代收集理論

?分代收集名為理論,實(shí)質(zhì)是一套符合大多數(shù)程序運(yùn)行實(shí)際情況的經(jīng)驗(yàn)法則事格,它建立在兩個(gè)分代假說(shuō)之上:

  • 弱分代假說(shuō):絕大多數(shù)對(duì)象都是朝生夕滅的惕艳。
  • 強(qiáng)分代假說(shuō):熬過(guò)越多次垃圾收集過(guò)程的對(duì)象就越難以消亡。
    ?根據(jù)以上兩種分代假說(shuō)驹愚,收集器應(yīng)該將Java堆劃分出不同的區(qū)域远搪,然后將回收對(duì)象依據(jù)年齡分配到不同的區(qū)域之中存儲(chǔ)。在新生代每次垃圾回收時(shí)都會(huì)有大批對(duì)象死去逢捺,JVM將難以回收的對(duì)象放到老年代以低頻率來(lái)回收這個(gè)區(qū)域谁鳍。
    ?新生代和老年代之間可能存在引用,假設(shè)在新生代進(jìn)行垃圾收集蒸甜,但是新生代對(duì)象可能被老年代對(duì)象引用,為了找出新生代中的存活對(duì)象余佛,不得不在固定的GC Roots之外柠新,再額外便利整個(gè)老年代中所有對(duì)象來(lái)確保可達(dá)性分析結(jié)果的正確性辉巡,反之也存在可能恨憎。這種方式無(wú)疑是會(huì)帶來(lái)性能負(fù)擔(dān)的,因此引入了跨代引用假說(shuō)郊楣。
  • 跨代引用假說(shuō)
    ?例如在新生代上建立一個(gè)全局的數(shù)據(jù)結(jié)構(gòu)憔恳,把老年代劃分成若干個(gè)小塊,標(biāo)識(shí)出哪一塊內(nèi)存會(huì)存在跨代引用净蚤,此后發(fā)生垃圾收集時(shí)就不用遍歷整個(gè)老年代钥组。

4.2 回收類型

  • 部分收集(Partil GC)
    ① 新生代收集(Minor GC/Young GC)
    ② 老年代收集 (Major GC/Old GC)
    ③ 混合GC(mixed GC):指目標(biāo)是收集整個(gè)新生代以及部分老年代的垃圾收集。目前只有G1 收集器會(huì)有這種行為今瀑。
  • 整堆收集(Full GC):收集整個(gè)Java堆和方法區(qū)的垃圾收集程梦。

4.3 標(biāo)記-清除算法

4.4 標(biāo)記-復(fù)制算法(半?yún)^(qū)復(fù)制)

4.5 標(biāo)記-整理算法


5 ART垃圾回收

?我們都知道Android 5.0之后ART虛擬機(jī)用于完全取代了Dalvik虛擬機(jī)点把,ART引入了預(yù)編譯技術(shù)AOT(Ahead-Of-Time compile)相比Dalvik的即時(shí)編譯技術(shù)(Just-In-Time compile),AOT減少了運(yùn)行時(shí)重復(fù)編譯程序無(wú)用功屿附。

在Android 5.0之前只有標(biāo)記清除算法一種策略

在Android 5.0之后郎逃,ART增加了標(biāo)記復(fù)制算法和標(biāo)記整理算法

?ART在程序處于前臺(tái)時(shí)使用標(biāo)記清除算法,處于后臺(tái)時(shí)使用標(biāo)記整理算法挺份,在前臺(tái)切換后臺(tái)時(shí)或者后臺(tái)切換前臺(tái)時(shí),ActivityManager會(huì)通知發(fā)生一次標(biāo)記復(fù)制算法褒翰。


總結(jié)

?標(biāo)記清除、標(biāo)記復(fù)制匀泊、標(biāo)記整理算法觸發(fā)STW(Stop The World)造成線程全部暫時(shí)停掉(它們耗時(shí)的長(zhǎng)短和前面的順序一樣)优训,ART何時(shí)使用垃圾收集清理算法是根據(jù)用于處于前臺(tái)還是后臺(tái)來(lái)動(dòng)態(tài)選擇清理算法的。
?目前來(lái)說(shuō)只能通過(guò)修改build.prop改變堆的大小等屬性探赫,因此我們?nèi)粘i_發(fā)的上層應(yīng)用是無(wú)法修改堆屬性的型宙。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市伦吠,隨后出現(xiàn)的幾起案子妆兑,更是在濱河造成了極大的恐慌,老刑警劉巖毛仪,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搁嗓,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡箱靴,警方通過(guò)查閱死者的電腦和手機(jī)腺逛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)衡怀,“玉大人棍矛,你說(shuō)我怎么就攤上這事∨籽睿” “怎么了够委?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)怖现。 經(jīng)常有香客問(wèn)我茁帽,道長(zhǎng),這世上最難降的妖魔是什么屈嗤? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任潘拨,我火速辦了婚禮,結(jié)果婚禮上饶号,老公的妹妹穿的比我還像新娘铁追。我一直安慰自己,他們只是感情好茫船,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布脂信。 她就那樣靜靜地躺著癣蟋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狰闪。 梳的紋絲不亂的頭發(fā)上疯搅,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音埋泵,去河邊找鬼幔欧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛丽声,可吹牛的內(nèi)容都是我干的礁蔗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼雁社,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼浴井!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起霉撵,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤磺浙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后徒坡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撕氧,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年喇完,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伦泥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锦溪,死狀恐怖不脯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情刻诊,我是刑警寧澤防楷,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站坏逢,受9級(jí)特大地震影響域帐,放射性物質(zhì)發(fā)生泄漏赘被。R本人自食惡果不足惜是整,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望民假。 院中可真熱鬧浮入,春花似錦、人聲如沸羊异。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至易迹,卻和暖如春宰衙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背睹欲。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工供炼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人窘疮。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓袋哼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親闸衫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子涛贯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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