深入java虛擬機(jī)第9章, 垃圾收集(1)關(guān)鍵字: jvmjava虛擬機(jī)的堆里存放著正在運(yùn)行的java程序所創(chuàng)建的所有對(duì)象。當(dāng)一個(gè)對(duì)象不再被程序引用時(shí),它所使用的堆空間可以被回收,以便后續(xù)的新對(duì)象所使用。垃圾收集器必須能夠斷定哪些對(duì)象是不再被引用的,并且能夠把它們所占據(jù)的堆空間釋放出來。在釋放不再被引用的對(duì)象的過程中,垃圾收集器運(yùn)行將要被釋放的對(duì)象的終結(jié)方法(finalizer)。 除了釋放不再被引用的對(duì)象,垃圾收集器還要處理堆碎片。在一個(gè)虛擬內(nèi)存系統(tǒng)中,增長的堆所需要的額外分頁(或交換)空間會(huì)影響運(yùn)行程序的性能。
垃圾收集 垃圾收集算法要做兩件事情 1) 檢測出垃圾對(duì)象 2)回收垃圾對(duì)象所使用的堆空間并還給程序
垃圾檢測通常通過建立一個(gè)根對(duì)象的集合并且檢查從這些根對(duì)象開始的可觸及性來實(shí)現(xiàn)。如果正在執(zhí)行的程序可以訪問到的根對(duì)象和某個(gè)對(duì)象之前存在引用路徑,這個(gè)對(duì)象就是可觸及的。對(duì)于程序來說,根對(duì)象總是可以訪問的。從這個(gè)根對(duì)象開始,任何可以被觸及的對(duì)象都被認(rèn)為是活動(dòng)對(duì)象。無法被觸及的對(duì)象被認(rèn)為是垃圾,因?yàn)樗鼈儾辉谟绊懗绦虻膱?zhí)行。
java虛擬機(jī)的根對(duì)象集合根據(jù)實(shí)現(xiàn)而不同,但是總會(huì)包含局部變量中的對(duì)象引用和棧幀的操作數(shù)棧(以及類變量中的對(duì)象引用)。另一個(gè)根對(duì)象的來源是被加載的類的常量池中的對(duì)象引用,比如字符串。還有一個(gè)來源是傳遞到本地方法中的,沒有被本地方法釋放的對(duì)象引用。另一個(gè)潛在的根對(duì)象的來源是,java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)中從垃圾收集器的堆中分配的部分。
區(qū)分活動(dòng)對(duì)象和垃圾的兩個(gè)基本方法是引用計(jì)數(shù)和跟蹤。 引用計(jì)數(shù)垃圾收集器通過為堆中的每一個(gè)對(duì)象保存一個(gè)計(jì)數(shù)來區(qū)分活動(dòng)對(duì)象和垃圾對(duì)象。這個(gè)計(jì)數(shù)記錄下了對(duì)那個(gè)對(duì)象的引用次數(shù)。 跟蹤垃圾收集器實(shí)際上追蹤從根結(jié)點(diǎn)開始的引用圖。在追蹤中遇上的對(duì)象以某種方式打上標(biāo)記,當(dāng)追蹤結(jié)束時(shí),沒有被打上標(biāo)記的對(duì)象就是被斷定是不可觸及的,可以被當(dāng)作垃圾收集。
//因此當(dāng)主線程啟動(dòng)一個(gè)子線程,并且主線程以以上任何一種方式退出后. 子線程是否繼續(xù)執(zhí)行取決于這個(gè)線程是用戶線程還是守護(hù)線程.如果該子線程是用戶線程,該子線程會(huì)繼續(xù)執(zhí)行. //這里寫得有問題 應(yīng)該是java程序啟動(dòng)一個(gè)線程,并且java程序以以上任何一種方式退出后. 在主線程退出,在jvm退出之前.jvm會(huì)判斷當(dāng)前的進(jìn)程. 如果在沒有用戶進(jìn)程(有或沒有守護(hù)線程)的情況下,jvm會(huì)退出 該線程是否繼續(xù)執(zhí)行取決于這個(gè)線程是用戶線程還是守護(hù)線程.如果該線程是用戶線程,該線程會(huì)繼續(xù)執(zhí)行. |
|
|