每日一個知識點:什麼時候會觸發Full GC

架構核心技術發表於2020-10-16

每日一個知識點系列的目的是針對某一個知識點進行概括性總結,可在一分鐘內完成知識點的閱讀理解。

此處不涉及詳細的原理性解讀,只作為一種拋磚引玉。

真正的理解一定是你自我研究探索所收穫的知識,加入組織帶你一起進步成長。

世界上最快的捷徑,就是腳踏實地。本文已收錄架構技術專欄關注這個喜歡分享的地方,每日獲得一個知識點

1. 呼叫 System.gc()

只是建議虛擬機器執行 Full GC,但是虛擬機器不一定真正去執行。不建議使用這種方式,而是讓虛擬機器管理記憶體。

2. 未指定老年代和新生代大小,堆伸縮時會產生fullgc,所以一定要配置-Xmx、-Xms

3. 老年代空間不足

老年代空間不足的常見場景比如大物件、大陣列直接進入老年代、長期存活的物件進入老年代等。

為了避免以上原因引起的 Full GC,應當儘量不要建立過大的物件以及陣列。

除此之外,可以通過 -Xmn 虛擬機器引數調大新生代的大小,讓物件儘量在新生代被回收掉,不進入老年代。

還可以通過 -XX:MaxTenuringThreshold 調大物件進入老年代的年齡,讓物件在新生代多存活一段時間。

在執行Full GC後空間仍然不足,則丟擲錯誤:java.lang.OutOfMemoryError: Java heap space

4. JDK 1.7 及以前的(永久代)空間滿

在 JDK 1.7 及以前,HotSpot 虛擬機器中的方法區是用永久代實現的,永久代中存放的為一些 Class 的資訊、常量、靜

態變數等資料。

當系統中要載入的類、反射的類和呼叫的方法較多時,永久代可能會被佔滿,在未配置為採用 CMS GC 的情況下也

會執行 Full GC。

如果經過 Full GC 仍然回收不了,那麼虛擬機器會丟擲java.lang.OutOfMemoryError PermGen space

為避免以上原因引起的 Full GC,可採用的方法為增大Perm Gen或轉為使用 CMS GC。

5. 空間分配擔保失敗

空間擔保,下面兩種情況是空間擔保失敗:

1、每次晉升的物件的平均大小 > 老年代剩餘空間

2、Minor GC後存活的物件超過了老年代剩餘空間

注意GC日誌中是否有promotion failed和concurrent mode failure兩種狀況,當出現這兩種狀況的時候就有可能會觸發Full GC。

promotion failed 是在進行 Minor GC時候,survivor space空間放不下只能晉升老年代,而此時老年代也空間不足時發生的。

concurrent mode failure 是在進行CMS GC過程,此時有物件要放入老年代而空間不足造成的,這種情況下會退化使用Serial Old收集器變成單執行緒的,此時是相當的慢的。

怎麼調優

圍繞一個點,策略就是儘量把物件在新生代使用回收,減少晉升老年代的機率

開源專案:

  • 分散式監控(Gitee GVP最有價值開源專案 ):https://gitee.com/sanjiankethree/cubic

  • 攝像頭視訊流採集:https://gitee.com/sanjiankethree/cubic-video

  • Github 文章收錄:https://github.com/qianglu1989/technology

相關文章