判斷哪些對(duì)象需要被GC
- 堆
- 方法區(qū)
可達(dá)性分析方法(Java使用):通過(guò)判斷對(duì)象是否被GC Root 直接或間接引用,進(jìn)而判斷對(duì)象是否可用,如果對(duì)象不可以就可以對(duì)這個(gè)對(duì)象進(jìn)行GC
引用計(jì)數(shù)方法(python使用):每個(gè)對(duì)象有一個(gè)引用計(jì)數(shù)屬性,新增一個(gè)引用時(shí)計(jì)數(shù)加1,引用釋放時(shí)計(jì)數(shù)減1,計(jì)數(shù)為0時(shí)可以回收。此方法簡(jiǎn)單,但無(wú)法解決對(duì)象相互循環(huán)引用的問(wèn)題。
如何觸發(fā)GC
- 程序調(diào)用System.gc()
- 根據(jù)Eden區(qū)和FromSpace區(qū)的內(nèi)存大小來(lái)決定,如果內(nèi)存不足,則會(huì)啟動(dòng)GC(此時(shí)應(yīng)用線程停止)
GC又分為 minor GC 和 Full GC (也稱為 Major GC )
Minor GC觸發(fā)條件:當(dāng)Eden區(qū)滿時(shí),觸發(fā)Minor GC。
Full GC觸發(fā)條件:
a.調(diào)用System.gc時(shí),系統(tǒng)建議執(zhí)行Full GC,但是不必然執(zhí)行
b.老年代空間不足
c.方法去空間不足
d.通過(guò)Minor GC后進(jìn)入老年代的平均大小大于老年代的可用內(nèi)存
e.由Eden區(qū)、From Space區(qū)向To Space區(qū)復(fù)制時(shí),對(duì)象大小大于To Space可用內(nèi)存,則把該對(duì)象轉(zhuǎn)存到老年代,且老年代的可用內(nèi)存小于該對(duì)象大小
GC算法
GC常用算法有:標(biāo)記-清除算法,標(biāo)記-壓縮算法,復(fù)制算法,分代收集算法。
新生代、老年代的轉(zhuǎn)化過(guò)程
具體過(guò)程:新生代(Young)分為Eden區(qū),F(xiàn)rom區(qū)與To區(qū)

當(dāng)系統(tǒng)創(chuàng)建一個(gè)對(duì)象的時(shí)候,總是在Eden區(qū)操作,當(dāng)這個(gè)區(qū)滿了,那么就會(huì)觸發(fā)一次YoungGC,也就是年輕代的垃圾回收。一般來(lái)說(shuō)這時(shí)候不是所有的對(duì)象都沒(méi)用了,所以就會(huì)把還能用的對(duì)象復(fù)制到From區(qū)。

這樣整個(gè)Eden區(qū)就被清理干凈了,可以繼續(xù)創(chuàng)建新的對(duì)象,當(dāng)Eden區(qū)再次被用完,就再觸發(fā)一次YoungGC,然后呢,注意,這個(gè)時(shí)候跟剛才稍稍有點(diǎn)區(qū)別。這次觸發(fā)YoungGC后,會(huì)將Eden區(qū)與From區(qū)還在被使用的對(duì)象復(fù)制到To區(qū),

再下一次YoungGC的時(shí)候,則是將Eden區(qū)與To區(qū)中的還在被使用的對(duì)象復(fù)制到From區(qū)。

經(jīng)過(guò)若干次YoungGC后,有些對(duì)象在From與To之間來(lái)回游蕩,這時(shí)候From區(qū)與To區(qū)亮出了底線(閾值),這些家伙要是到現(xiàn)在還沒(méi)掛掉,對(duì)不起,一起滾到(復(fù)制)老年代吧。

老年代經(jīng)過(guò)這么幾次折騰,也就扛不住了(空間被用完),好,那就來(lái)次集體大掃除(Full GC),也就是全量回收。如果Full GC使用太頻繁的話,無(wú)疑會(huì)對(duì)系統(tǒng)性能產(chǎn)生很大的影響。所以要合理設(shè)置年輕代與老年代的大小,盡量減少Full GC的操作。