JVM原理—垃圾回收機(jī)制算法


在面向?qū)ο笳Z言程序中袍榆,我們的程序在運(yùn)行中會創(chuàng)建很多對象最岗,程序會為對象在內(nèi)存中開辟一段空間并分配好內(nèi)存地址烙常,當(dāng)對象使用結(jié)束后磷蜀,需要釋放占用的內(nèi)存空間召耘,釋放對象內(nèi)存的機(jī)制就叫垃圾回收機(jī)制(Garbage Collection,GC)褐隆。在C語言中污它,動態(tài)分配內(nèi)存用 malloc() 函數(shù),釋放內(nèi)存用 free() 函數(shù)庶弃,而C++中衫贬,我們則使用運(yùn)算符 new 和 delete 來管理內(nèi)存,這樣雖然能靈活有效的申請和釋放內(nèi)存歇攻,但是對程序員來說固惯,有時(shí)候使一種負(fù)擔(dān),而Java的垃圾回收機(jī)制則很好的解決了這一問題缴守。

一葬毫、垃圾回收機(jī)制:

JVM自動不定時(shí)去堆內(nèi)存中清理不可達(dá)對象。不可達(dá)的對象并不會馬上就會直接回收屡穗,垃圾收集器在一個Java程序中的執(zhí)行是自動的贴捡,不能強(qiáng)制執(zhí)行,即使程序員能明確地判斷出有一塊內(nèi)存已經(jīng)無用了村砂,是應(yīng)該回收的烂斋,程序員也不能強(qiáng)制垃圾收集器回收該內(nèi)存塊。程序員唯一能做的就是通過調(diào)用System.gc 方法來"建議"執(zhí)行垃圾收集器础废,但其是否可以執(zhí)行源祈,什么時(shí)候執(zhí)行卻都是不可知的。這也是垃圾收集器的最主要的缺點(diǎn)色迂。當(dāng)然相對于它給程序員帶來的巨大方便性而言香缺,這個缺點(diǎn)是瑕不掩瑜的。

1. 不可達(dá)對象:?對象沒有被引用歇僧,獲知對象沒有存活图张。

2. finalize方法:

Java在垃圾收集器將對象從內(nèi)存中清除出去前,使用finalize()方法做必要的清理工作诈悍。該方法在Object類中定義祸轮,因此所有的類都繼承了它。子類覆蓋finalize()方法以整理系統(tǒng)資源或者執(zhí)行其他清理工作侥钳。finalize方法是在垃圾收集器刪除對象之前對這個對象調(diào)用的适袜。

3. 新生代和老年代:

堆內(nèi)存被劃分成兩個不同的區(qū)域:新生代 ( Young )、老年代 ( Old )舷夺。

新生代 ( Young ) 又被劃分為三個區(qū)域:Eden苦酱、From Survivor(S0)售貌、To Survivor(S1)。S0區(qū)和S1區(qū)內(nèi)存大小相等疫萤。

新生代:剛new出不久的對象存放在新生代中颂跨,存放不經(jīng)常被使用的對象。

老年代:存放比較活躍的對象扯饶,存放經(jīng)常被引用的對象恒削。

垃圾回收機(jī)制在新生代回收的次數(shù)比較頻繁,而在老年代回收的次數(shù)相對較少尾序。而且一般情況下钓丰,老年代的內(nèi)存空間大于新生代的內(nèi)存空間。

二每币、判斷對象存活的方法:

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

給對象中添加一個引用計(jì)數(shù)器携丁,每當(dāng)有一個地方引用它時(shí),計(jì)數(shù)器值加1脯爪;當(dāng)引用失效時(shí)则北,計(jì)數(shù)器值減1矿微。任何時(shí)刻計(jì)數(shù)器值為0的對象就是不可能再被使用的痕慢。當(dāng)對象計(jì)數(shù)器的值大于15時(shí),會被存放到堆內(nèi)存的老年代中涌矢,當(dāng)對象的值大于0小于15時(shí)則存放在新生代中掖举。因其很難解決對象之間相互循環(huán)引用的問題,所以該算法逐漸被淘汰娜庇,而別很少出現(xiàn)在主流的Java虛擬機(jī)中塔次。

2.根搜索算法:

根搜索算法的基本思路就是通過一系列名為”GC Roots”的對象作為起始點(diǎn),從這些節(jié)點(diǎn)開始向下搜索名秀,搜索所走過的路徑稱為引用鏈(Reference Chain)励负,當(dāng)一個對象到GC Roots沒有任何引用鏈相連時(shí),則證明此對象是不可用的匕得。

在Java語言中继榆,可以作為GCRoots的對象包括下面幾種:

(1). 棧(棧幀中的局部變量區(qū),也叫做局部變量表)中引用的對象汁掠。

(2). 方法區(qū)中的類靜態(tài)屬性引用的對象略吨。

(3). 方法區(qū)中常量引用的對象。

(4). 本地方法棧中JNI(Native方法)引用的對象考阱。

三翠忠、垃圾回收策略:

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

標(biāo)記階段:遍歷堆乞榨,將不可達(dá)對象標(biāo)記為1秽之,可達(dá)對象標(biāo)記為0当娱。

清除階段:遍歷堆,逐個把標(biāo)記為1的不可達(dá)對象回收政溃。

缺點(diǎn):由于堆內(nèi)存空間不連續(xù)趾访,所以逐個回收對象時(shí)會產(chǎn)生內(nèi)存空間碎片化,而且效率低董虱。

應(yīng)用場景:用于對象存活周期較長的老年代扼鞋。

2、復(fù)制算法:

復(fù)制算法的基本思想是JVM一開始就會將可用內(nèi)存分為大小相等的兩塊:from域(S0區(qū))和to域(S1區(qū))愤诱。每次只是使用from域云头,to域則空閑著。當(dāng)from域內(nèi)存不夠了淫半,開始執(zhí)行GC操作溃槐,這個時(shí)候,會把from域存活的對象拷貝到to域科吭,然后直接把from域進(jìn)行內(nèi)存清理昏滴。

應(yīng)用場景:新生代。在新生代中对人,內(nèi)存會被分為Eden區(qū)谣殊、S0區(qū)和S1區(qū)。剛new出來的對象剛開始會被存放在Eden區(qū)牺弄,當(dāng)Eden區(qū)內(nèi)存滿后姻几,觸發(fā)新生代的GC操作,把可達(dá)對象拷貝至S0區(qū)势告,清除Eden區(qū)中的所有對象蛇捌,當(dāng)Eden區(qū)再次觸發(fā)GC操作時(shí),會掃描Eden區(qū)和S0區(qū)域咱台,對兩個區(qū)域進(jìn)行垃圾回收络拌,經(jīng)過這次回收后還存活的對象,則直接復(fù)制到S1區(qū)域回溺,并將Eden和From區(qū)域清空春贸;當(dāng)后續(xù)Eden又發(fā)生GC回收時(shí),會對Eden和S1區(qū)域進(jìn)行垃圾回收馅而,存活的對象復(fù)制到S0區(qū)域祥诽,并將Eden和S1區(qū)清空;如此交換15次(由JVM參數(shù)MaxTenuringThreshold決定,這個參數(shù)默認(rèn)是15)瓮恭,最終如果還是存活雄坪,就存入到老年代。

優(yōu)缺點(diǎn):性能高屯蹦,解決了碎片化問題维哈,但是S0和S1區(qū)總有一塊內(nèi)存空白绳姨,造成內(nèi)存空間浪費(fèi)。

應(yīng)用場景:新生代阔挠。

3飘庄、標(biāo)記壓縮算法:

在標(biāo)記清除算法的基礎(chǔ)上,將對象進(jìn)行排序购撼,使不可達(dá)對象盡可能地排序在一起跪削,GC操作時(shí)就可整段刪除不可達(dá)對象,從而解決標(biāo)記清除算法中產(chǎn)生碎片化的問題迂求。

4碾盐、分代算法:

根據(jù)對象的存活周期的不同將內(nèi)存劃分成幾塊,新生代和老年代揩局,這樣就可以根據(jù)各個年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴ê辆痢P律捎脧?fù)制算法,老年代使用標(biāo)記壓縮算法凌盯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載付枫,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末驰怎,一起剝皮案震驚了整個濱河市阐滩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌砸西,老刑警劉巖叶眉,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件址儒,死亡現(xiàn)場離奇詭異芹枷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)莲趣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門鸳慈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喧伞,你說我怎么就攤上這事走芋。” “怎么了潘鲫?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵翁逞,是天一觀的道長。 經(jīng)常有香客問我溉仑,道長挖函,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任浊竟,我火速辦了婚禮怨喘,結(jié)果婚禮上津畸,老公的妹妹穿的比我還像新娘。我一直安慰自己必怜,他們只是感情好肉拓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著梳庆,像睡著了一般暖途。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上膏执,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天丧肴,我揣著相機(jī)與錄音,去河邊找鬼胧后。 笑死芋浮,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的壳快。 我是一名探鬼主播纸巷,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼眶痰!你這毒婦竟也來了瘤旨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤竖伯,失蹤者是張志新(化名)和其女友劉穎存哲,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體七婴,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祟偷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了打厘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片修肠。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖户盯,靈堂內(nèi)的尸體忽然破棺而出嵌施,到底是詐尸還是另有隱情,我是刑警寧澤莽鸭,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布吗伤,位于F島的核電站,受9級特大地震影響硫眨,放射性物質(zhì)發(fā)生泄漏足淆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缸浦。 院中可真熱鬧夕冲,春花似錦、人聲如沸裂逐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卜高。三九已至弥姻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掺涛,已是汗流浹背庭敦。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留薪缆,地道東北人秧廉。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像拣帽,于是被迫代替她去往敵國和親疼电。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354