對(duì)于 Minor GC,其觸發(fā)條件非常簡(jiǎn)單,當(dāng) Eden 空間滿時(shí),就將觸發(fā)一次 Minor GC。而 Full GC 則相對(duì)復(fù)雜,有以下條件:
1、調(diào)用 System.gc()
只是建議虛擬機(jī)執(zhí)行 Full GC,但是虛擬機(jī)不一定真正去執(zhí)行。不建議使用這種方式,而是讓虛擬機(jī)管理內(nèi)存。
2、老年代空間不足
老年代空間不足的常見場(chǎng)景為前文所講的大對(duì)象直接進(jìn)入老年代、長(zhǎng)期存活的對(duì)象進(jìn)入老年代等。
為了避免以上原因引起的 Full GC,應(yīng)當(dāng)盡量不要?jiǎng)?chuàng)建過大的對(duì)象以及數(shù)組。除此之外,可以通過 -Xmn 虛擬機(jī)參數(shù)調(diào)大新生代的大小,讓對(duì)象盡量在新生代被回收掉,不進(jìn)入老年代。還可以通過 -XX:MaxTenuringThreshold 調(diào)大對(duì)象進(jìn)入老年代的年齡,讓對(duì)象在新生代多存活一段時(shí)間。
3、空間分配擔(dān)保失敗
使用復(fù)制算法的 Minor GC 需要老年代的內(nèi)存空間作擔(dān)保,如果擔(dān)保失敗會(huì)執(zhí)行一次 Full GC。
4、JDK 1.7 及以前的永久代空間不足
在 JDK 1.7 及以前,HotSpot 虛擬機(jī)中的方法區(qū)是用永久代實(shí)現(xiàn)的,永久代中存放的為一些 Class 的信息、常量、靜態(tài)變量等數(shù)據(jù)。
當(dāng)系統(tǒng)中要加載的類、反射的類和調(diào)用的方法較多時(shí),永久代可能會(huì)被占滿,在未配置為采用 CMS GC 的情況下也會(huì)執(zhí)行 Full GC。如果經(jīng)過 Full GC 仍然回收不了,那么虛擬機(jī)會(huì)拋出 java.lang.OutOfMemoryError。
為避免以上原因引起的 Full GC,可采用的方法為增大永久代空間或轉(zhuǎn)為使用 CMS GC。
5、Concurrent Mode Failure
執(zhí)行 CMS GC 的過程中同時(shí)有對(duì)象要放入老年代,而此時(shí)老年代空間不足(可能是 GC 過程中浮動(dòng)垃圾過多導(dǎo)致暫時(shí)性的空間不足),便會(huì)報(bào) Concurrent Mode Failure 錯(cuò)誤,并觸發(fā) Full GC。