Java 中GC - 垃圾回收機(jī)制

1. 為什么需要垃圾回收


如果不進(jìn)行垃圾回收棘催,內(nèi)存遲早被消耗空葛闷,因?yàn)槲覀冊(cè)诓粩喾峙鋬?nèi)存而沒(méi)有回收退盯,除非內(nèi)存無(wú)限大,我們可以任意分配不用回收辞色,但事實(shí)并非如此,所以砚哗,我們必須要進(jìn)行垃圾回收怔揩。

2. 哪些內(nèi)存需要回收


一些不再被使用的對(duì)象,比如我們?cè)贏ctivity琼稻、Fragment中的onDestroy()方法中把所有findViewById找到的控件置為null的這些對(duì)象吮螺,需要被回收。

3. 什么是JVM堆


3.1 JVM堆概念

JVM堆——是Java中對(duì)象的活動(dòng)空間范圍帕翻,代碼中的類里邊的對(duì)象是從 JVM堆中分配空間的鸠补,它里邊存儲(chǔ)著正在運(yùn)行的應(yīng)用程序中所有的對(duì)象,而這些對(duì)象的建立方式就是 new對(duì)象的那些操作嘀掸,當(dāng)對(duì)象不用了紫岩,是GC負(fù)責(zé)無(wú)用回收的對(duì)象

3.2 JVM堆

1>新域:存儲(chǔ)所有新生成的對(duì)象;
2>舊域:新域中的對(duì)象睬塌,經(jīng)過(guò)一定次數(shù)的GC循環(huán)后泉蝌,被移入舊域;
3>永久域:存儲(chǔ)類揩晴、方法梨与、對(duì)象,這個(gè)類是獨(dú)立的文狱,不包含在JVM堆中粥鞋,默認(rèn)為4M

4. JVM垃圾回收機(jī)制


java對(duì)內(nèi)存的釋放采取的是 —— 垃圾自動(dòng)回收機(jī)制,寫代碼時(shí)不用考慮 變量在不用的時(shí)候需要釋放內(nèi)存瞄崇,JVM(即就是java虛擬機(jī))會(huì)自動(dòng)判斷并收集垃圾呻粹,一般不會(huì)立即釋放它們的內(nèi)存空間,也可以手動(dòng)調(diào)用System.gc()苏研,表示強(qiáng)制立即回收垃圾等浊,即就是釋放內(nèi)存,注意摹蘑,系統(tǒng)并不會(huì)保證立即釋放內(nèi)存筹燕。

5. 什么是GC


GC(Garbage Collection)就是垃圾回收器,Java開(kāi)發(fā)人員不能像C衅鹿、C++開(kāi)發(fā)人員一樣使用指針來(lái)管理內(nèi)存撒踪,GC是JVM對(duì)內(nèi)存(其實(shí)就是對(duì)象)進(jìn)行管理的方式。程序員不用擔(dān)心內(nèi)存管理大渤,因?yàn)槔厥掌鲿?huì)自動(dòng)進(jìn)行管理制妄。GC使開(kāi)發(fā)人員擺脫了繁瑣的內(nèi)存管理工作,提高開(kāi)發(fā)效率泵三。

6. GC的基本原理


Java內(nèi)存管理耕捞,實(shí)際上就是對(duì) 對(duì)象的管理衔掸,包括對(duì)象的創(chuàng)建和釋放。創(chuàng)建就是new對(duì)象俺抽,釋放對(duì)象就是將其置為null敞映,讓程序不再能訪問(wèn)到這個(gè)對(duì)象,稱該對(duì)象為 "不可達(dá)的"磷斧,GC負(fù)責(zé)回收所有 "不可達(dá)的"對(duì)象的內(nèi)存空間振愿。

7. GC的目的


在堆中,找到無(wú)用的對(duì)象瞳抓,并把這些對(duì)象占用的空間收回讓其重新利用。
大多數(shù)垃圾回收算法思路都是一樣的:把所有對(duì)象組成一個(gè)集合伏恐,或者理解為樹狀結(jié)構(gòu)孩哑,從樹根開(kāi)始找,只要找到的都是活動(dòng)的對(duì)象翠桦,如果找不到横蜒,就說(shuō)明該對(duì)象已經(jīng)不再被使用了,就可以回收了销凑。

8. GC中回收算法


1>:標(biāo)記 - 清除算法

分為兩個(gè)階段丛晌,首先標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象斗幼。
缺點(diǎn)是:標(biāo)記和清除效率都不高澎蛛,可能會(huì)產(chǎn)生很多碎片;

2>:標(biāo)記 - 整理算法

標(biāo)記整理與標(biāo)記清除算法過(guò)程一樣蜕窿,但是后邊不是簡(jiǎn)單的清除谋逻,而是讓所有存活的對(duì)象都向一端移動(dòng),然后清除邊界值以外的內(nèi)存桐经;

3>:復(fù)制算法

將可用內(nèi)存按容量劃分為相等的兩塊毁兆,每次只用其中一塊,當(dāng)這一塊用完阴挣,就將還存活的對(duì)象復(fù)制到另一塊上面气堕,然后把原始空間全部回收。高效畔咧、簡(jiǎn)單茎芭。
缺點(diǎn):將內(nèi)存縮小為原來(lái)一半;

4>:分代收集算法

新生代中誓沸,每次垃圾收集時(shí)都會(huì)有大批對(duì)象死去骗爆,只有少量存活,可以用復(fù)制算法蔽介,只需要付出少量存活對(duì)象的復(fù)制成本摘投,就可以完成收集煮寡;
老年代中,其存活率較高犀呼、沒(méi)有額外空間對(duì)它進(jìn)行分配擔(dān)保幸撕,就用 "標(biāo)記清除或者標(biāo)記整理"算法進(jìn)行回收。

9.建議


1.一般都是在Activity外臂、Fragment中的onDestroy()方法中把所有findViewById找到的對(duì)象全部置為null坐儿,在使用這種方式時(shí),需要注意一些復(fù)雜的對(duì)象圖宋光,比如:數(shù)組貌矿、隊(duì)列、樹罪佳、圖等逛漫,這些對(duì)象之間相互引用關(guān)系比較復(fù)雜,GC的回收效率也會(huì)比較低赘艳,如果程序允許酌毡,盡早將不用的 引用對(duì)象置為null,這樣可以加速GC的運(yùn)行速度蕾管;

  1. 盡量少用finalize()方法枷踏,finalize()方法是Java提供給程序員一個(gè)釋放對(duì)象或者釋放資源的機(jī)會(huì),但是它會(huì)加大GC的工作量掰曾,因此盡量少用finalize()方法來(lái)回收資源旭蠕;
  2. 如果需要使用 經(jīng)常使用的圖片,可以使用 soft(SoftReference)軟引用類型旷坦,它可以盡可能的將圖片保存在內(nèi)存中下梢,可供程序調(diào)用,不引起OOM塞蹭;
  3. 對(duì)于數(shù)組孽江、隊(duì)列、樹番电、圖等岗屏,這些數(shù)據(jù)結(jié)構(gòu)對(duì)于GC來(lái)說(shuō),回收更為復(fù)雜漱办,注意一些全局的變量这刷、靜態(tài)的變量,這些變量可能會(huì)引起內(nèi)存浪費(fèi)娩井;
  4. 當(dāng)程序有一定的等待時(shí)間暇屋,可以手動(dòng)執(zhí)行System.gc(),通知GC運(yùn)行洞辣。

9. 總結(jié)


1.JVM堆的大小決定了GC的運(yùn)行時(shí)間咐刨,如果JVM堆的大小超過(guò)一定限度昙衅,那么GC的運(yùn)行時(shí)間會(huì)很長(zhǎng);
2.對(duì)象的生存時(shí)間越長(zhǎng)定鸟,GC需要回收的時(shí)間也越長(zhǎng)而涉,影響回收速度;
3.如果GC運(yùn)行周期超過(guò)3-5秒联予,會(huì)很影響程序的運(yùn)行啼县,如果可以就需要減小JVM堆的大小沸久;
4.通常情況JVM堆的大小應(yīng)該為物理內(nèi)存的80%季眷;

  1. 應(yīng)用程序中,創(chuàng)建與釋放對(duì)象的速度決定了垃圾回收的頻率卷胯;
  2. 大多數(shù)對(duì)象都是短命的子刮,如果能讓這些對(duì)象的生存周期在GC的一次運(yùn)行周期內(nèi)就非常好了。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诵竭,一起剝皮案震驚了整個(gè)濱河市话告,隨后出現(xiàn)的幾起案子兼搏,更是在濱河造成了極大的恐慌卵慰,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佛呻,死亡現(xiàn)場(chǎng)離奇詭異裳朋,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)吓著,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門鲤嫡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人绑莺,你說(shuō)我怎么就攤上這事暖眼。” “怎么了纺裁?”我有些...
    開(kāi)封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵诫肠,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我欺缘,道長(zhǎng)栋豫,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任谚殊,我火速辦了婚禮丧鸯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嫩絮。我一直安慰自己丛肢,他們只是感情好围肥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著摔踱,像睡著了一般虐先。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上派敷,一...
    開(kāi)封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天蛹批,我揣著相機(jī)與錄音,去河邊找鬼篮愉。 笑死腐芍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的试躏。 我是一名探鬼主播猪勇,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼颠蕴!你這毒婦竟也來(lái)了泣刹?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤犀被,失蹤者是張志新(化名)和其女友劉穎椅您,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寡键,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡掀泳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了西轩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片员舵。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖藕畔,靈堂內(nèi)的尸體忽然破棺而出马僻,到底是詐尸還是另有隱情,我是刑警寧澤注服,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布韭邓,位于F島的核電站,受9級(jí)特大地震影響祠汇,放射性物質(zhì)發(fā)生泄漏仍秤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一可很、第九天 我趴在偏房一處隱蔽的房頂上張望诗力。 院中可真熱鬧,春花似錦、人聲如沸苇本。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瓣窄。三九已至笛厦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間俺夕,已是汗流浹背裳凸。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留劝贸,地道東北人姨谷。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像映九,于是被迫代替她去往敵國(guó)和親梦湘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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