資源描述:
《javagc系列(2):java垃圾回收是如何工作的?-java開(kāi)發(fā)java經(jīng)驗(yàn)技巧》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫(kù)。
1、JavaGC系列(2):Java垃圾回收是如何工作的?-編程開(kāi)發(fā)技術(shù)JavaGC系列(2):Java垃圾回收是如何工作的?本文illImportNew-伍羽巾翻譯口javapapers□歡迎加入翻譯小組。轉(zhuǎn)載詰見(jiàn)文末要求。目錄1.垃圾回收介紹2.垃圾回收是如何工作的?3.垃圾回收的類(lèi)別4.垃圾回收監(jiān)視和分析本教程是為了理解基本的Java垃圾冋收以及它是如何工作的。這是垃圾冋收教程系列的第二部分。希望你已經(jīng)讀過(guò)了第一部分:《Java垃圾回收介紹》。Java垃圾回收是一項(xiàng)自動(dòng)化的過(guò)程,用來(lái)管理程序所使用的運(yùn)行時(shí)內(nèi)存。通
2、過(guò)這一口動(dòng)化過(guò)程,JVM解除了程序員在程序中分配和釋放內(nèi)存資源的開(kāi)銷(xiāo)。啟動(dòng)Java垃圾回收作為一個(gè)自動(dòng)的過(guò)程,程序員不需要在代碼屮顯示地啟動(dòng)垃圾回收過(guò)程。System.gc()和Runtime.gc()用來(lái)請(qǐng)求JVM啟動(dòng)垃圾回收。雖然這個(gè)請(qǐng)求機(jī)制提供給程序員一個(gè)啟動(dòng)GC過(guò)程的機(jī)會(huì),但是啟動(dòng)由JVM負(fù)責(zé)。JVM可以拒絕這個(gè)請(qǐng)求,所以并不保證這些調(diào)用都將執(zhí)行垃圾回收。啟動(dòng)時(shí)機(jī)的選擇由JVM決定,并口取決于堆內(nèi)存中Eden區(qū)是否可用。JVM將這個(gè)選擇留給了Java規(guī)范的實(shí)現(xiàn),不同實(shí)現(xiàn)具體使用的算法不盡相同。毋庸置疑,我們
3、知道垃圾冋收過(guò)程是不能被強(qiáng)制執(zhí)行的。我剛剛發(fā)現(xiàn)了一個(gè)調(diào)用System,gc()有意義的場(chǎng)景。通過(guò)這篇文章了解一下適合調(diào)用System.gc()這種極端情況。Java垃圾回收過(guò)程垃圾回收是一種回收無(wú)用內(nèi)存空間并使其對(duì)未來(lái)實(shí)例口J用的過(guò)程。Eden區(qū):當(dāng)一個(gè)實(shí)例被創(chuàng)建了,首先會(huì)被存儲(chǔ)在堆內(nèi)存年輕代的Eden區(qū)中。注意:如果你不能理解這些詞匯,我建議你閱讀這篇?垃圾冋收介紹,這篇教程詳細(xì)地介紹了內(nèi)存模型、JVM架構(gòu)以及這些術(shù)語(yǔ)。Survivor區(qū)(SO和S1):作為年輕代GC(MinorGC)周期的一部分,存活的對(duì)象(仍
4、然被引用的)從Eden區(qū)被移動(dòng)到Survivor區(qū)的SO中。類(lèi)似的,垃圾回收器會(huì)掃描SO然后將存活的實(shí)例移動(dòng)到S1屮。(譯注:此處不應(yīng)該是Eden和SO屮存活的都移到S1么,為什么會(huì)先移到SO再?gòu)腟O移到S1?)死亡的實(shí)例(不再被引用)被標(biāo)記為垃圾冋收。根據(jù)垃圾冋收器(有四種常用的垃圾回收器,將在下一?教程中介紹它們)選擇的不同,要么被標(biāo)記的實(shí)例都會(huì)不停地從內(nèi)存中移除,要么回收過(guò)程會(huì)在一個(gè)單獨(dú)的進(jìn)程中完成。老年代:?老年代(Oldortenuredgeneration)是堆內(nèi)存屮的第二塊邏輯區(qū)。當(dāng)垃圾冋收器執(zhí)彳亍M
5、inorGC周期時(shí),在SISurvivorIX中的存活實(shí)例將會(huì)被晉升到老年代,而未被引用的對(duì)象被標(biāo)記為回收。老年代GC(MajorGC):相對(duì)于Java垃圾冋收過(guò)程,老年代是實(shí)例生命周期的最后階段。MajorGC掃描老年代的垃圾回收過(guò)程。如果實(shí)例不再被引用,那么它們會(huì)被標(biāo)記為回收,否則它們會(huì)繼續(xù)留在老年代屮。內(nèi)存碎片:一旦實(shí)例從堆內(nèi)存中被刪除,其位置就會(huì)變空并且可用于未來(lái)實(shí)例的分配。這些空出的空間將會(huì)使整個(gè)內(nèi)存區(qū)域碎片化。為了實(shí)例的快速分配,需要進(jìn)行碎片整理。基于垃圾冋收器的不同選擇,冋收的內(nèi)存區(qū)域要么被不停地被整
6、理,要么在一個(gè)單獨(dú)的GC進(jìn)程中完成。垃圾回收中實(shí)例的終結(jié)在釋放一個(gè)實(shí)例和回收內(nèi)存空間Z前,Java垃圾回收器會(huì)調(diào)用實(shí)例各自的?finalize()?方法,從而該實(shí)例有機(jī)會(huì)釋放所持有的資源。雖然可以保證?finalize()?會(huì)在回收內(nèi)存空間之前被調(diào)用,但是沒(méi)有指定的順序和吋間。多個(gè)實(shí)例間的順序是無(wú)法被預(yù)知,英至可能會(huì)并行發(fā)生。程序不應(yīng)該預(yù)先調(diào)整實(shí)例Z間的順序并使用?finalizc()?方法回收資源。?任何在finalizeit程中未被捕獲的界常會(huì)口動(dòng)被忽略,然后該實(shí)例的finalize過(guò)程被取消。?JVM規(guī)范屮并
7、沒(méi)有討論關(guān)于弱引川的垃圾回收機(jī)制,也沒(méi)有很明確的要求。具體的實(shí)現(xiàn)都由實(shí)現(xiàn)方?jīng)Q定。?垃圾回收是由一個(gè)守護(hù)線程完成的。?所有實(shí)例都沒(méi)有活動(dòng)線程訪問(wèn)。?沒(méi)有被其他任何實(shí)例訪問(wèn)的循壞引用實(shí)例。Java中有不同的引用類(lèi)型。判斷實(shí)例是否符合垃圾收集的條件都依賴(lài)于它的引用類(lèi)型。引用類(lèi)型強(qiáng)引用(StrongReference)軟引用(SoftReference)弱引用(WeakReferenee)虛引用(PhantomReference)垃圾收集不符合垃圾收集垃圾收集可能會(huì)執(zhí)行,但會(huì)作為最后的選擇符合垃圾收集符合垃圾收集在編譯過(guò)程
8、中作為一種優(yōu)化技術(shù),Java編譯器能選擇給實(shí)例賦?null?值,從而標(biāo)記實(shí)例為可回收。classAnimal{publicstaticvoidmain(String[]args)Animallion=newAnimal();Systein.out?printin(,zMainiscompleted.”);protectedvoidfinalize(){Sys