Java11中新增了兩個GC,Epsilon GC和ZGC。
Epsilon垃圾收集器
A NoOp Garbage Collector
沒有操作的垃圾收集器
JDK上對這個特性的描述是:開發一個處理內存分配但不實現任何實際內存回收機制的GC, 一旦可用堆內存用完,JVM就會退出。
如果有System.gc()調用,實際上什么也不會發生(這種場景下和-XX:+DisableExplicitGC效果一樣), 因為沒有內存回收,這個實現可能會警告用戶嘗試強制GC是徒勞。
用法
-XX:+UnlockExperimentalVMOptions
-XX:+UseEpsilonGC
測試默認GC
我們寫一段代碼,不斷的產生垃圾:
public class EpsilonTest {
public static void main(String[] args) {
boolean flag = true;
List<Garbage> garbageList = new ArrayList<>();
int count = 0;
while (flag) {
garbageList.add(new Garbage());
if (count ++ == 500) {
garbageList.clear();
}
}
}
}
class Garbage {
private double d1 = 1;
private double d2 = 2;
/**
* 在GC清除對象時會調用一次
*/
@Override
protected void finalize() throws Throwable {
System.out.println(this + " collecting");
}
}
直接運行,使用的默認的垃圾回收器:
java11.Garbage@37c7d031 collecting
java11.Garbage@71a19bf9 collecting
java11.Garbage@3b2df791 collecting
java11.Garbage@61441b29 collecting
java11.Garbage@680b1968 collecting
java11.Garbage@158829c3 collecting
java11.Garbage@414dc59c collecting
java11.Garbage@1103cf collecting
......
從運行打印的結果可以看出:有對象被回收了,觸發了GC【默認用的是G1】
因為我只限定回收了500個,500個之后的對象會不斷加到內存中,內存就會不夠用:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java11.EpsilonTest.main(EpsilonTest.java:16)
測試Epsilon GC
如果我使用的是Epsilon GC,會是什么樣的結果呢?
使用方法
啟動時添加VM參數:
運行結果
運行代碼,發現控制台沒有任何的輸出,即EpsilonGC不會做任何的回收,並且程序很快就因為堆空間不足而退出。
Terminating due to java.lang.OutOfMemoryError: Java heap space
使用這個選項的原因
提供完全被動的GC實現, 具有有限的分配限制和盡可能低的延遲開銷,但代價是內存占用和內存吞吐量.
眾所周知, java實現可廣泛選擇高度可配置的GC實現. 各種可用的收集器最終滿足不同的需求, 即使它們的可配置性使它們的功能相交. 有時更容易維護單獨的實現, 而不是在現有GC實現上堆積另一個配置選項.
主要用途
- 性能測試(它可以幫助過濾掉GC引起的性能假象)
- 內存壓力測試(例如,知道測試用例 應該分配不超過1GB的內存, 我們可以使用-Xmx1g –XX:+UseEpsilonGC, 如果程序有問題, 則程序會崩潰)
- 非常短的JOB任務(對象這種任務, 接受GC清理堆那都是浪費空間)
- VM接口測試
- Last-drop 延遲&吞吐改進
ZGC
ZGC, A Scalable Low-Latency Garbage Collector(Experimental)
ZGC是一款可伸縮、低延遲的GC
概述
ZGC,應該是JDK11最為矚目的特性。但是后面帶了Experimental,說明這還不建議用到生產環境。
- GC暫停時間不會超過10ms
- 既能處理幾百兆的小堆, 也能處理幾個T的大堆(OMG)
- 和G1相比, 應用吞吐能力不會下降超過15%
- 為未來的GC功能和利用colord指針以及Load barriers優化奠定基礎
- 初始只支持64位系統
ZGC的設計目標是:支持TB級內存容量,暫停時間低(<10ms),對整個程序吞吐量的影響小於15%。 將來還可以擴展實現機制,以支持不少令人興奮的功能,例如多層堆(即熱對象置於DRAM和冷對象置於NVMe閃存),或壓縮堆。
在使用G1的時候,在回收垃圾的時候,必須要保證應用程序當中所有的線程停下來,不在內存中制造混亂,然后GC才會開始工作,會造成停頓。這一個過程,有一個專屬名詞來解釋:STW(stop the world)。
ZGC的目標就是縮短STW的時間:ZGC是一個並發,基於region, 壓縮型的垃圾收集器,只有root掃描階段會STW, 因此GC停頓時間不會隨着堆的增長和存活對象的增長而變長。
用法
-XX:+UnlockExperimentalVMOptions
-XX:+UseZGC
ps:ZGC暫時不能在windows系統中使用,不知道最新的版本有沒有支持,我手邊沒有windows機器,未做測試。