執(zhí)行GC的線程屬于VM Thread益兄,不是Java Thread。
什么時候觸發(fā)GC?
(1)當(dāng)剩余Eden空間不夠裝下新創(chuàng)建的對象實例時觸發(fā)MinorGC痊乾;
(2)當(dāng)老年代剩余空間不夠裝下直接丟進(jìn)老年代或者到達(dá)晉升年齡的對象時觸發(fā)FullGC喘批;
觸發(fā)GC后撩荣,需要掛起所有的Java Thread,來執(zhí)行GC Roots的可達(dá)性分析算法獲取可達(dá)對象和不可達(dá)對象饶深。
如何掛起所有的Java Thread餐曹?
在JVM發(fā)起GC時,可以先忽略處于sleep或者blocked的Java線程敌厘,因為這些Java線程在進(jìn)入sleep或者blocked狀態(tài)時已經(jīng)標(biāo)記自己進(jìn)入了Safe Region台猴,在離開sleep或者blocked狀態(tài)時,會檢查系統(tǒng)是否已經(jīng)完成了GC俱两,如果完成了就繼續(xù)執(zhí)行饱狂,如果沒有就繼續(xù)等待,直到收到GC完成的信號為止宪彩。
然后通過設(shè)置安全點休讳,可以在不太長的時間內(nèi)讓所有正在運行的Java線程遇到安全點,順利地被掛起毯焕。
最后衍腥,開始GC。
-- 設(shè)置安全點
保證正在執(zhí)行的線程在不太長的時間內(nèi)會遇到GC的safe point纳猫;
缺點:對于當(dāng)前沒有在執(zhí)行的線程婆咸,比如處于sleep或者blocked的線程,就不是很有效
-- 設(shè)置安全區(qū)域
基本想法:當(dāng)一個線程因sleep或者處于blocked而沒有在執(zhí)行時芜辕,其對應(yīng)的代碼片段中變量及對象的引用關(guān)系是不會發(fā)生變化的尚骄,所以只需要在一個線程在進(jìn)入sleep或者blocked時,標(biāo)識自己進(jìn)入了Safe Region侵续,從而在一個線程sleep或者blocked期間倔丈,JVM發(fā)生GC了,
問題: