資源描述:
《jvm垃圾回收器工作原理及使用實(shí)例介紹-java開(kāi)發(fā)java經(jīng)驗(yàn)技巧》由會(huì)員上傳分享,免費(fèi)在線(xiàn)閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫(kù)。
1、JVM垃圾回收器工作原理及使用實(shí)例介紹-編程開(kāi)發(fā)技術(shù)JVM垃圾回收器工作原理及使用實(shí)例介紹原文出處:周明耀垃圾收集基礎(chǔ)Java語(yǔ)言的一大特點(diǎn)就是可以進(jìn)行自動(dòng)垃圾回收處理,而無(wú)需開(kāi)發(fā)人員過(guò)于關(guān)注系統(tǒng)資源,例如內(nèi)存資源的釋放情況。自動(dòng)垃圾收集雖然大大減輕了開(kāi)發(fā)人員的工作量,但是也增加了軟件系統(tǒng)的負(fù)擔(dān)。擁冇垃圾收集器可以說(shuō)是Java語(yǔ)言與C++語(yǔ)言的一項(xiàng)顯著區(qū)別。在C++語(yǔ)言中,程序員必須小心謹(jǐn)慎地處理每一項(xiàng)內(nèi)存分配,且內(nèi)存使用完后必須手工釋放曾經(jīng)占用的內(nèi)存空間。當(dāng)內(nèi)存釋放不夠完全吋,即存在分配但永不釋放的內(nèi)存塊,就會(huì)引起內(nèi)存泄漏,嚴(yán)重時(shí)甚至導(dǎo)
2、致程序癱瘓。以卜?列舉了垃圾回收器常用的算法及實(shí)驗(yàn)原理:?引用計(jì)數(shù)法(ReferenceCounting)引用計(jì)數(shù)器在微軟的COM組件技術(shù)中、Adobe的ActionScript3種都有使用。引用計(jì)數(shù)器的實(shí)現(xiàn)很簡(jiǎn)單,對(duì)于一個(gè)對(duì)象A,只要有任何一個(gè)對(duì)象引用了A,則A的引用計(jì)數(shù)器就加1,當(dāng)引用失效時(shí),引用計(jì)數(shù)器就減lo只要對(duì)象A的引用計(jì)數(shù)器的值為0,則對(duì)象A就不可能再被使用。引用計(jì)數(shù)器的實(shí)現(xiàn)也非常簡(jiǎn)單,只需要為每個(gè)對(duì)象配置一個(gè)整形的計(jì)數(shù)器即可。但是引用計(jì)數(shù)器有一個(gè)嚴(yán)重的問(wèn)題,即無(wú)法處理循環(huán)引用的情況。因此,在Java的垃圾回收器中沒(méi)有使用這種
3、算法。一個(gè)簡(jiǎn)單的循環(huán)引用問(wèn)題描述如下:有對(duì)象A和對(duì)象B,對(duì)象A中含冇對(duì)象B的引用,對(duì)象B中含有對(duì)象A的引用。此時(shí),對(duì)象A和對(duì)象B的引用計(jì)數(shù)器都不為0o但是在系統(tǒng)屮卻不存在任何第3個(gè)對(duì)彖引用了A或B。也就是說(shuō),A和B是應(yīng)該被冋收的垃圾對(duì)彖,但由于垃圾對(duì)彖間相互引用,從而使垃圾冋收器無(wú)法識(shí)別,引起內(nèi)存泄漏。?標(biāo)記■清除算法(Mark-Sweep)標(biāo)記-清除算法將垃圾回收分為兩個(gè)階段:標(biāo)記階段和清除階段。一種可行的實(shí)現(xiàn)是,在標(biāo)記階段首先通過(guò)根節(jié)點(diǎn),標(biāo)記所有從根節(jié)點(diǎn)開(kāi)始的較大對(duì)象。因此,未被標(biāo)記的對(duì)象就是未被引用的垃圾對(duì)象。然后,在清除階段,清除
4、所有未被標(biāo)記的對(duì)象。該算法最大的問(wèn)題是存在大量的空間碎片,因?yàn)榛厥蘸蟮目臻g是不連續(xù)的。在對(duì)象的堆空間分配過(guò)程中,尤其是大對(duì)象的內(nèi)存分配,不連續(xù)的內(nèi)存空間的工作效率要低于連續(xù)的空間。?復(fù)制算法(Copying)將現(xiàn)有的內(nèi)存空間分為兩快,每次只使用其中一塊,在垃圾回收時(shí)將正在使用的內(nèi)存中的存活對(duì)象復(fù)制到未被使用的內(nèi)存塊中,Z后,清除正在使用的內(nèi)存塊中的所冇對(duì)彖,交換兩個(gè)內(nèi)存的角色,完成垃圾回收。如果系統(tǒng)中的垃圾對(duì)彖很多,復(fù)制算法需要復(fù)制的存活對(duì)象數(shù)量并不會(huì)太大。因此在真正需要垃圾回收的吋刻,復(fù)制算法的效率是很高的。又由于對(duì)象在垃圾冋收過(guò)程中統(tǒng)
5、一被復(fù)制到新的內(nèi)存空間中,因此,可確?;厥蘸蟮膬?nèi)存空間是沒(méi)冇碎片的。該算法的缺點(diǎn)是將系統(tǒng)內(nèi)存折半。Java的新生代串行垃圾回收器中使用了復(fù)制算法的思想。新生代分為eden空間、from空間、to空間3個(gè)部分。其中from空間和to空間可以視為用于復(fù)制的兩塊大小相同、地位相等,且可進(jìn)行角色互換的空間塊。from和to空間也稱(chēng)為survivor空間,即幸存者空間,用于存放未被冋收的對(duì)象。在垃圾回收時(shí),cdcn空間中的存活對(duì)象會(huì)被復(fù)制到未使用的survivor空間中(假設(shè)是to),正在使用的survivor空間(假設(shè)是from)屮的年輕對(duì)彖也會(huì)
6、被復(fù)制到to空間中(大對(duì)彖,或者老年對(duì)象會(huì)直接進(jìn)入老年帶,如果to空間己滿(mǎn),則對(duì)象也會(huì)直接進(jìn)入老年代)。此時(shí),eden空間和from空間屮的剩余對(duì)象就是垃圾對(duì)象,可以直接清空,to空間則存放此次回收后的存活對(duì)象。這種改進(jìn)的復(fù)制算法既保證了空間的連續(xù)性,又避免了大量的內(nèi)存空間浪費(fèi)。?標(biāo)記-壓縮算法(Mark-Compact)復(fù)制算法的高效性是建立在存活對(duì)象少、垃圾對(duì)象多的前提下的。這種情況在年輕代經(jīng)常發(fā)生,但是在老年代更常見(jiàn)的情況是大部分對(duì)象都是存活對(duì)象。如果依然使用復(fù)制算法,由于存活的對(duì)象較多,復(fù)制的成本也將很高。標(biāo)記-壓縮算法是一種老年
7、代的回收算法,它在標(biāo)記-清除算法的基礎(chǔ)上做了一些優(yōu)化。也首先需要從根節(jié)點(diǎn)開(kāi)始對(duì)所有可達(dá)對(duì)彖做一次標(biāo)記,但Z后,它并不簡(jiǎn)單地清理未標(biāo)記的對(duì)彖,而是將所有的存活對(duì)象壓縮到內(nèi)存的一端。之后,清理邊界外所有的空間。這種方法既避免了碎片的產(chǎn)生,又不需要兩塊相同的內(nèi)存空間,因此,其性?xún)r(jià)比比較高。?增量算法(IncrementalCollecting)在垃圾回收過(guò)程中,應(yīng)用軟件將處于一種CPU消耗很高的狀態(tài)。在這種CPU消耗很高的狀態(tài)下,應(yīng)用程序所有的線(xiàn)程都會(huì)掛起,暫停一切止常的工作,等待垃圾回收的完成。如果垃圾回收時(shí)間過(guò)長(zhǎng),應(yīng)用程序會(huì)被掛起很久,將嚴(yán)
8、重影響用戶(hù)體驗(yàn)或者系統(tǒng)的穩(wěn)定性。增量算法的基本思想是,如果一次性將所冇的垃圾進(jìn)行處理,需耍造成系統(tǒng)長(zhǎng)時(shí)間的停頓,那么就可以讓垃圾收集線(xiàn)程和應(yīng)用程序線(xiàn)程交替執(zhí)行。毎次,垃圾收集線(xiàn)程只收集一小片區(qū)