瞎掰JVM:內存結構---垃圾回收(一)

上一篇主要記錄了JAVA的內存模型,主要爲虛擬機詮釋內存控制的主要概念,是併發場景編程的基礎。下面記錄一下內存的垃圾回收,是虛擬機性能調優和錯誤診斷方面的基礎。

垃圾在各代上分別回收,年輕代上發生的回收叫Minor GC ,發生一次GC的條件是:Eden 區滿。那survivor 區滿了怎麼辦?會發生一次晉升,可能觸發一次Major GC/Full GC.MixedGC  是G1收集器中獨有的概念,負責部分年輕代和全部老年代的垃圾整理。

Full GC/Major GC 的觸發條件有:

  1. 老年代空間不足

這種情況特指創建過大的對象和數組直接分配在老年代分配內存空間時發生,虛擬機有個參數PretenureSizeThreshold,可以控制直接進入老年代的對象大小,需要注意的時該參數只對Serial和ParNew兩款收集器有效,Parallel Scavenge收集器不認識這個參數,Parallel Scavenge收集器一般並不需要設置。如果遇到必須使用此參數的場合,可以考慮ParNew加CMS的收集器組合。ParNew是CMS默認使用的年輕代收集器。

      2. 擔保失敗

如果發現統計數據說之前Minor GC的平均晉升大小比目前old gen剩餘的空間大,則不會觸發Minor GC而是轉爲觸發full GC. 這也是上面所說的情況.虛擬機參數-XX:+HandlePromotionFailure 控制擔保開啓。

      3. 晉升失敗(老年代空間不足的第二種情況)

由Eden區、From Space區向To Space區複製時,對象大小大於To Space可用內存,則把該對象轉存到老年代,且老年代的可用內存小於該對象大小。在配置CMS收集器的情況下,promotion failed就是這種情況,這種原因經常由於併發收集器產生的碎片導致可用空間不足;concurrent mode failure是在執行CMS GC的過程中同時有對象要放入舊生代,而此時舊生代空間不足造成的。

      4. 永久代空間不足

JVM規範中運行時數據區域中的方法區,在HotSpot虛擬機中又被習慣稱爲永生代或者永生區,Permanet Generation中存放的爲一些class的信息、常量、靜態變量等數據,當系統中要加載的類、反射的類和調用的方法較多時,Permanet Generation可能會被佔滿,在未配置爲採用CMS GC的情況下也會執行Full GC。如果經過Full GC仍然回收不了,那麼JVM會拋出如下錯誤信息:
java.lang.OutOfMemoryError: PermGen space
爲避免Perm Gen佔滿造成Full GC現象,可採用的方法爲增大Perm Gen空間或轉爲使用CMS GC。

        5. System.gc

此方法的調用是建議JVM進行Full GC,雖然只是建議而非一定,但很多情況下它會觸發 Full GC,從而增加Full GC的頻率,也即增加了間歇性停頓的次數。強烈影響系建議能不使用此方法就別使用,讓虛擬機自己去管理它的內存,可通過通過-XX:+ DisableExplicitGC來禁止調用System.gc 觸發回收。

 

MixedGC 觸發條件:

1. InitiatingHeapOccupancyPercent:堆佔有率達到這個值則觸發global concurrent marking,默認45%

2. G1HeapWastePercent:在global concurrent marking結束之後,可以知道區有多少空間要被回收,在每次YGC之後和再次發生Mixed GC之前,會檢查垃圾佔比是否達到了此參數,只有達到了,下次纔會發生Mixed GC

需要同時滿足以上兩個條件可觸發

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章