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