第三章 垃圾收集器與內(nèi)存分配策略

對象存活判定算法

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

原理是每個(gè)對象都有一個(gè)引用計(jì)數(shù)器,當(dāng)被引用時(shí),計(jì)數(shù)器加1格侯,取消引用時(shí)計(jì)數(shù)器減1。計(jì)數(shù)器為0時(shí)表明該對象不再被其他對象引用企蹭,就可以回收。
弊端是當(dāng)出現(xiàn)循環(huán)引用時(shí)無法回收,導(dǎo)致內(nèi)存泄露。

可達(dá)性分析算法

原理是通過一系列成為GC ROOTS的對象作為根節(jié)點(diǎn)套像,開始向下搜索,所走過的路徑成為引用鏈终息,當(dāng)一個(gè)對象通過任何引用鏈都不可達(dá)時(shí),這個(gè)對象就會被回收贞让。
可以作為GC roots的對象包括:

  • 虛擬機(jī)棧(棧幀中的本地變量表)中引用的對象周崭。
  • 方法區(qū)中類靜態(tài)屬性引用的對象。
  • 方法區(qū)中常量引用的對象
  • 本地方法棧中JNI(即一般說的Native方法)引用的對象喳张。

JAVA中的引用

  • 強(qiáng)引用
  • 軟引用
  • 弱引用
  • 虛引用

對象的自我救贖

當(dāng)對象在可達(dá)性分析算法中通過任何引用鏈都不可達(dá)時(shí)续镇,該對象也不會立即被回收。只是相當(dāng)于被判死緩销部。真正執(zhí)行死刑分兩次標(biāo)記階段:當(dāng)對象不可達(dá)時(shí)摸航,被第一次標(biāo)記并且篩選,看該對象是否有必要執(zhí)行finalize方法舅桩。如果該對象沒有覆蓋finalize方法或者該對象的finalize方法已經(jīng)被執(zhí)行過酱虎,則該對象就沒有必要執(zhí)行finalize方法。如果該對象被判定為有必要執(zhí)行finalize方法擂涛,那么這個(gè)對象將被放入一個(gè)叫做F-Queue的隊(duì)列中读串,然后由一個(gè)虛擬機(jī)自動建立的低優(yōu)先級的finalizer線程去執(zhí)行。所謂的執(zhí)行只代表觸發(fā)這個(gè)方法撒妈,并不會等待方法執(zhí)行結(jié)束恢暖,這是因?yàn)槿绻粋€(gè)對象在finalize方法中執(zhí)行緩慢或者出現(xiàn)死循環(huán),則這個(gè)線程將會被阻塞狰右,F(xiàn)-Queue中的其他對象永遠(yuǎn)處于等待中杰捂,整個(gè)內(nèi)存回收系統(tǒng)會崩潰。finalize才能決定該對象最后的命運(yùn)棋蚌。如果在finalize方法中重新與引用鏈 中 的對象建立關(guān)聯(lián)嫁佳,譬如把自己賦值給某個(gè)類變量或者對象的成員變量挨队,在第二次標(biāo)記時(shí)該對象將被從F-Queue隊(duì)列中移除。剩下的對象將被真的回收脱拼。但是如果被移除的對象又一次被判死刑瞒瘸,則finalize方法也拯救不了它了,因?yàn)閒inalize方法只會被執(zhí)行一次熄浓。(這就好比一個(gè)女人被判了死刑情臭,但是執(zhí)行死刑前發(fā)現(xiàn)該犯人懷孕了,那就不會被執(zhí)行死刑了赌蔑。但是這免死金牌只能用一次俯在。)

垃圾收集算法

  • 標(biāo)記-清除算法
    是其他收集算法的基礎(chǔ)。缺點(diǎn)是標(biāo)記和清除階段效率都比較低娃惯,而且會導(dǎo)致內(nèi)存碎片問題跷乐。
  • 復(fù)制算法
    原理是把內(nèi)存分為大小相等的兩塊,每次分配只在其中一塊上進(jìn)行分配趾浅,當(dāng)這塊內(nèi)存用完的時(shí)候就將還存活的對象復(fù)制到另一塊中愕提,然后將這塊全部清理掉。這樣使得每次都是對整個(gè)半?yún)^(qū)進(jìn)行回收皿哨,而且也沒有碎片問題浅侨,只要移動堆頂指針,按順序分配內(nèi)存即可证膨。優(yōu)點(diǎn)是比較簡單如输,效率比較高。缺點(diǎn)是將可用內(nèi)存縮減為原來的一半了央勒,代價(jià)比較高不见,而且如果存活對象比較多,則復(fù)制操作就會比較多崔步,效率就會變低稳吮。年輕代的垃圾回收算法采用此算法。
  • 標(biāo)記-整理算法
    原理是標(biāo)記過程依然與“標(biāo)記-清理”算法中的標(biāo)記過程一樣井濒。只是在清理階段是將存活對象移動到一起盖高,然后將剩下的空間清理。
  • 分代收集算法

垃圾收集器

  • Serial收集器(年輕代采用)
    它是個(gè)單線程的收集器眼虱。在進(jìn)行垃圾收集時(shí)必須暫停其他所有的工作線程喻奥。STOP THE WORLD。優(yōu)點(diǎn)是簡單高效捏悬。
  • ParNew收集器(年輕代采用)
    ParNew收集器是Serial收集器的多線程版本撞蚕。
  • Parallel Scavenge收集器(年輕代采用)
    也被稱為“吞吐量優(yōu)先收集器”。機(jī)制上也是多線程的过牙,與ParNew收集器一樣甥厦。但是它的關(guān)注點(diǎn)不是盡可能的縮短用戶線程等待時(shí)間纺铭,而是達(dá)到一個(gè)可控制吞吐量。另外Parallel Scavenge收集器有一個(gè)自適應(yīng)調(diào)節(jié)策略刀疙,即虛擬機(jī)會根據(jù)當(dāng)前系統(tǒng)的運(yùn)行情況收集性能監(jiān)控信息舶赔,然后動態(tài)的調(diào)整參數(shù)來提供合適的停頓時(shí)間或者提升最大的吞吐量。
  • Serial Old收集器(老年代采用)
    Serial Old收集器是Serial收集器的年老代版本谦秧。也是單線程的竟纳,但是使用“標(biāo)記-整理”算法。
  • Parallel Old收集器(老年代采用)
    它是Parallel Scavenge收集器的老年代版本疚鲤。使用多線程和“標(biāo)記-整理”算法锥累。
  • CMS(Concurrent Mark Sweep)收集器
    基于“標(biāo)記-清除”算法實(shí)現(xiàn)。目標(biāo)是停頓時(shí)間最短集歇,適合服務(wù)端應(yīng)用桶略。
    運(yùn)作過程分四個(gè)步驟:
    1、初始標(biāo)記诲宇。該階段只標(biāo)記GC ROOTS能直接關(guān)聯(lián)到的對象际歼。需要STOP THE WORLD。
    2姑蓝、并發(fā)標(biāo)記蹬挺。該階段開始整個(gè)引用鏈的標(biāo)記過程,是和用戶線程并發(fā)執(zhí)行的它掂。
    3、重新標(biāo)記溯泣。該階段是為了修正并發(fā)標(biāo)記階段因?yàn)橛脩舫绦虺掷m(xù)運(yùn)行而導(dǎo)致的變動虐秋。
    4、并發(fā)清除垃沦。該階段也是和用戶線程并發(fā)執(zhí)行的客给。
    該收集器優(yōu)點(diǎn):并發(fā)收集、低停頓肢簿。
    缺點(diǎn):并發(fā)階段需要占用一部分線程靶剑,搶占CPU,所以勢必導(dǎo)致用戶線程的執(zhí)行變慢池充。無法處理浮動垃圾桩引。而且由于基于“標(biāo)記-清除”算法,所以會產(chǎn)生內(nèi)存碎片收夸。
  • G1收集器
    特點(diǎn):
    1坑匠、并行與并發(fā)。
    2卧惜、分代收集
    3厘灼、空間整合
    4夹纫、可預(yù)測的停頓

內(nèi)存分配與回收策略

  • 對象優(yōu)先在Eden區(qū)分配
  • 大對象直接在老年代分配。虛擬機(jī)提供了一個(gè)-XX:PretenureSizeThreshold參數(shù)來設(shè)置设凹。
  • 長期存活的對象將進(jìn)入老年代舰讹。每個(gè)對象都有年齡計(jì)數(shù)器,虛擬機(jī)默認(rèn)設(shè)置的是15歲進(jìn)入老年代闪朱。-XX:MaxTenuringThreshold設(shè)置月匣。
  • 動態(tài)對象年齡判定
    如果在Survivor空間中相同年齡的所有對象大小的總和大于Survivor空間的一般,年齡大于或等于該年齡的對象就可以直接進(jìn)入老年代無須達(dá)到年齡监透。
  • 空間分配擔(dān)保
    在發(fā)生MinorGC之前桶错,虛擬機(jī)會檢查年老的最大可用的連續(xù)空間是否大于新生代所有對象總空間,如果大于胀蛮,則可以進(jìn)行MinorGC院刁;否則虛擬機(jī)會查看HandlePromotionFailure設(shè)置值是否允許擔(dān)保失敗,如果允許那么繼續(xù)檢查年老代最大可用的連續(xù)空間是否大于歷次晉升到老年代對象的平均大小粪狼,如果大于退腥,將嘗試進(jìn)行一次MinorGC,如果小于或者不允許擔(dān)保失敗再榄,則改為進(jìn)行FullGc狡刘。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市困鸥,隨后出現(xiàn)的幾起案子嗅蔬,更是在濱河造成了極大的恐慌,老刑警劉巖疾就,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件澜术,死亡現(xiàn)場離奇詭異,居然都是意外死亡猬腰,警方通過查閱死者的電腦和手機(jī)鸟废,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姑荷,“玉大人盒延,你說我怎么就攤上這事∈竺幔” “怎么了添寺?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長懈费。 經(jīng)常有香客問我畦贸,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任薄坏,我火速辦了婚禮趋厉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胶坠。我一直安慰自己君账,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布沈善。 她就那樣靜靜地躺著乡数,像睡著了一般。 火紅的嫁衣襯著肌膚如雪闻牡。 梳的紋絲不亂的頭發(fā)上净赴,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機(jī)與錄音罩润,去河邊找鬼玖翅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛割以,可吹牛的內(nèi)容都是我干的金度。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼严沥,長吁一口氣:“原來是場噩夢啊……” “哼猜极!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起消玄,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤跟伏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后翩瓜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體受扳,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年奥溺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骨宠。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡浮定,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出层亿,到底是詐尸還是另有隱情桦卒,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布匿又,位于F島的核電站方灾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜裕偿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一洞慎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嘿棘,春花似錦劲腿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至重父,卻和暖如春花椭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背房午。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工矿辽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人歪沃。 一個(gè)月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓嗦锐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親沪曙。 傳聞我的和親對象是個(gè)殘疾皇子奕污,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

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