Java 虛擬機垃圾回收策略簡要介紹

垃圾回收是什么蓖谢?

Java 虛擬機垃圾回收是指對不使用的內(nèi)存區(qū)域進行釋放阅畴,防止分配空間時因內(nèi)存不足而出現(xiàn)內(nèi)存溢出異常领斥。

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

垃圾回收主要發(fā)生在 Java 堆和方法區(qū)中哩都,Java 堆和方法區(qū)是 Java 虛擬機管理內(nèi)存中的兩個區(qū)域,其中 Java 堆主要是用來存放 Java 程序中的對象實例婉徘,方法區(qū)則用來存儲已加載的類信息漠嵌、常量、靜態(tài)變量等數(shù)據(jù)盖呼。Java 虛擬機管理的內(nèi)存中還有其他幾個區(qū)域:程序計數(shù)器儒鹿、Java 虛擬機棧、本地方法棧几晤、運行時常量池约炎、直接內(nèi)存,這幾個區(qū)域?qū)?nèi)存的使用比較具有確定性蟹瘾,所以不需要考慮回收策略,然而 Java 堆和方法區(qū)則不一樣,創(chuàng)建對象實例胎撇、加載類热幔、定義常量等操作都是在程序運行期間進行的,這兩個區(qū)域的內(nèi)存使用是動態(tài)的众雷,因此需要特定的垃圾回收策略進行管理內(nèi)存灸拍。

如何回收做祝?

一般是使用一種叫分代收集算法的綜合策略進行回收,這種算法是把內(nèi)存根據(jù)使用狀態(tài)的不同劃分為幾塊鸡岗。其中 Java 堆大致分為兩塊:新生代和老年代剖淀,新生代存儲新創(chuàng)建或變動頻繁的對象的內(nèi)存信息,老年代則存儲存活時間較長纤房、不經(jīng)常變動的對象的內(nèi)存信息纵隔。方法區(qū)內(nèi)存則一般分為永久代,這里的內(nèi)存變動頻率更加低炮姨,每次垃圾回收只有少數(shù)的廢棄常量和無用的類會被回收捌刮。下面主要說下針對新生代和老年代的內(nèi)存回收策略。

最基礎(chǔ)的策略是標記-清除算法舒岸,首先標記出所有需要回收的對象绅作,之后統(tǒng)一釋放對象占用的內(nèi)存空間。由于回收的對象在內(nèi)存中不一定是連續(xù)存儲的蛾派,所以這種算法執(zhí)行之后可能分產(chǎn)生大量不連續(xù)的內(nèi)存碎片俄认,這可能會導(dǎo)致因無法分配較大對象而再次觸發(fā)垃圾回收動作。

為了提高效率洪乍,針對新生代的垃圾回收一般采用復(fù)制算法眯杏,將內(nèi)存按容量比例分成8:1:1三塊內(nèi)存,其中8份為常用空間壳澳,剩下兩份為倆兩塊保留空間岂贩。使用內(nèi)存時使用常用空間和一塊保留空間,剩下一塊保留空間空閑不使用巷波,回收時萎津,將使用的內(nèi)存中存活的對象一次性復(fù)制到空閑的保留空間里,然后清理使用的常用空間和保留空間抹镊。如果在回收時锉屈,空閑的保留空間不夠用于存儲存活的對象時,那么會使用其他內(nèi)存區(qū)域如老年代進行分配擔保垮耳。

老年代中的對象存活率較高颈渊,采用復(fù)制算法效率反而會比較低,所以針對這塊的垃圾回收一般是直接使用標記-清除算法氨菇,或使用標記-整理算法儡炼,這種算法也是先標記對象,然后將存活的對象向內(nèi)存的一端移動查蓉,最后直接釋放邊界外的內(nèi)存區(qū)域即可乌询。

怎么判斷一個對象需要回收?

上面說到需要對要回收的對象進行先標記之后才能進行回收操作豌研,那么怎么知道那些對象需要回收呢妹田?
判斷對象是否可以繼續(xù)使用主要與對象的引用有關(guān)唬党,下表描述了一個對象的幾種引用狀態(tài)。

引用類型 失效時機 作用 實現(xiàn)
強引用 一直有效 防止一個對象被回收 直接引用鬼佣,如 Object o = new Object()
軟引用 內(nèi)存溢出之前失效 防止一個對象導(dǎo)致的內(nèi)存溢出 使用SoftReference類
弱引用 垃圾收集器工作時失效 防止一個對象導(dǎo)致的內(nèi)存泄漏 使用WeakReference類
虛引用 一直無效 可以收到一個對象被回收時的通知 使用PhantomReference類

判斷對象可用狀態(tài)一般的策略是使用引用計數(shù)算法驶拱,就是每個對象有一個引用計數(shù)器,沒當有一個有效的引用時晶衷,計數(shù)器就加1 蓝纲,當引用失效時,計數(shù)器就減1晌纫,計數(shù)器為0的對象就是不能再被使用的税迷,需要被回收。但這種策略會出現(xiàn)對象相互循環(huán)引用而無法回收的問題锹漱,舉例如下:

//a1箭养、a2的引用計數(shù)分別為1
A a1 = new A();
A a2 = new A();
//a2被a1的member成員引用,所以a2的引用計數(shù)為2
a1.member = a2;
//a1同a2哥牍,引用計數(shù)為2
a2.member = a1;


//a1毕泌、a2對象的引用計數(shù)減1,都為1
a1 = null;
a2 = null;

如果這時候采用引用計數(shù)法進行垃圾回收操作嗅辣,那么由于a1和a2對象引用計數(shù)不為0撼泛,將不會被回收。但其實 Java 虛擬機還是可以回收它們的辩诞,這是因為 Java 虛擬機使用了另外一種策略判斷對象是否可被回收坎弯,叫可達性分析算法。

可達性分析算法是先把一些對象看作是 GC Roots 對象译暂,對象間的引用關(guān)系可以看成 GC Roots 作為根節(jié)點而每個引用作為子節(jié)點的樹狀結(jié)構(gòu),如果一個對象在這顆樹之外撩炊,就是從 GC Roots 向下搜索找不到這個對象外永,那么可以說 GC Roots 到這個對象不可達,這個對象就是可以被回收的拧咳。

總結(jié)

本文對 Java 虛擬機中的垃圾回收進行了簡單的介紹伯顶,在 Java 堆中,它需要先根據(jù)對象的引用分析可達性骆膝,以標記出要回收的對象祭衩,然后使用分代收集算法進行回收,而在方法區(qū)中阅签,則是直接回收廢棄的常量和類信息掐暮,最終達到釋放內(nèi)存空間的目的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末政钟,一起剝皮案震驚了整個濱河市路克,隨后出現(xiàn)的幾起案子樟结,更是在濱河造成了極大的恐慌,老刑警劉巖精算,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓢宦,死亡現(xiàn)場離奇詭異,居然都是意外死亡灰羽,警方通過查閱死者的電腦和手機驮履,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來廉嚼,“玉大人疲吸,你說我怎么就攤上這事∏岸欤” “怎么了摘悴?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長舰绘。 經(jīng)常有香客問我蹂喻,道長,這世上最難降的妖魔是什么捂寿? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任口四,我火速辦了婚禮,結(jié)果婚禮上秦陋,老公的妹妹穿的比我還像新娘蔓彩。我一直安慰自己,他們只是感情好驳概,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布赤嚼。 她就那樣靜靜地躺著,像睡著了一般顺又。 火紅的嫁衣襯著肌膚如雪更卒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天稚照,我揣著相機與錄音蹂空,去河邊找鬼。 笑死果录,一個胖子當著我的面吹牛上枕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播弱恒,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼辨萍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了斤彼?” 一聲冷哼從身側(cè)響起分瘦,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蘸泻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嘲玫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悦施,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年去团,在試婚紗的時候發(fā)現(xiàn)自己被綠了抡诞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡土陪,死狀恐怖昼汗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鬼雀,我是刑警寧澤顷窒,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站源哩,受9級特大地震影響鞋吉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜励烦,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一谓着、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧坛掠,春花似錦赊锚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至系瓢,卻和暖如春阿纤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背夷陋。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留胰锌,地道東北人骗绕。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像资昧,于是被迫代替她去往敵國和親酬土。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

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