Java11新特性 - Epsilon GC和ZGC


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機器,未做測試。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM