ZGC什麼時候進行垃圾回收
對ZGC還不怎麼了解的同學,可以先看看這篇文章ZGC,一個超乎想象的垃圾收集器
以往的一些GC演算法,比如CMS、G1,採用分代的思想對堆記憶體進行劃分,對應的GC行為也可以分為Young GC、Old GC 和 FGC。
但是在ZGC演算法中,並沒有分代的概念,所以就不存在Young GC、Old GC,所有的GC行為都是Full GC。
那ZGC的垃圾回收行為什麼時候會進行?
擼了下原始碼,已經準確定位到觸發ZGC的邏輯,位於zDirector.cpp檔案。
虛擬機器啟動時,會啟動一個執行緒執行如下邏輯:
void ZDirector::run_service() { // Main loop while (_metronome.wait_for_tick()) { sample_allocation_rate(); const GCCause::Cause cause = make_gc_decision(); if (cause != GCCause::_no_gc) { ZCollectedHeap::heap()->collect(cause); } } }
其中_metronome.wait_for_tick()
每間隔100ms返回一次,意味著每100ms執行一次make_gc_decision()
,決定是否執行ZGC。
在make_gc_decision()
中提供了4種策略,只要滿足其中1個策略就可以觸發ZGC。
rule_timer
第一個策略,從行為表現上,我把它叫做是週期性GC,預設是不生效的,但是如果配置 -XX:ZCollectionInterval=1(單位是秒),那麼每隔1s,就會執行一次ZGC,太暴力了。
rule_warmup
JVM啟動之後,如果一直沒有發生過GC,那麼會在堆記憶體使用超過10%、20%、30%時,分別觸發一次GC,這樣做是為了收集一些GC相關的資料,為後面的條件規則提供資料支撐。
rule_allocation_rate
根據物件分配速率決定是否GC。
如果當前的可用堆記憶體,根據估計出來的物件最大分配速率,很快會被耗盡,則執行一次GC,這種策略一般在qps很高、物件分配很快時會被觸發。
rule_proactive
這個策略是積極主動型的。
如果能夠接受因為GC引起的應用吞吐量下降,那麼就觸發GC,這個策略允許我們降低堆記憶體,並且在堆記憶體還有很多剩餘空間時,執行引用處理,具體的條件是:
1、自從上次GC之後,堆的使用量至少漲了10%
2、自從上次GC之後,已經過去5分鐘沒有發生GC
這有助於在物件分配率非常低的應用程式時避免多餘的GC.
這4種都是在還有空閒記憶體的時候就執行GC的策略,那如果垃圾回收的速度趕不上物件分配的速率,怎麼辦?
這個時候,分配物件的應用執行緒,只能停下來,等待垃圾物件的回收,如果回收掉一部分記憶體,就可以直接拿到用了,不需要等垃圾回收執行完成。