1. 序章

Java 11は、Epsilonと呼ばれる No-Opガベージコレクターを導入しました。これは、可能な限り低いGCオーバーヘッドを約束します。

この短いチュートリアルでは、Epsilonがどのように機能するかを探り、一般的な使用例について説明します。

2. クイックハンズオン

手を汚すことから始めて、Epsilon GCを試してみましょう!

まず、ガベージを作成するアプリケーションが必要です。

class MemoryPolluter {

    static final int MEGABYTE_IN_BYTES = 1024 * 1024;
    static final int ITERATION_COUNT = 1024 * 10;

    static void main(String[] args) {
        System.out.println("Starting pollution");

        for (int i = 0; i < ITERATION_COUNT; i++) {
            byte[] array = new byte[MEGABYTE_IN_BYTES];
        }

        System.out.println("Terminating");
    }
}

このコードは、ループ内に1メガバイトの配列を作成します。 ループを10240回繰り返すので、10ギガバイトのメモリを割り当てることを意味します。これは、使用可能な最大ヒープサイズよりもおそらく大きいです。

また、アプリケーションがいつ終了するかを確認するためのヘルパープリントも提供しました。

Epsilon GCを有効にするには、次のVM引数を渡す必要があります。

-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC

また、アプリケーションを実行すると、次のエラーが発生します。

Starting pollution
Terminating due to java.lang.OutOfMemoryError: Java heap space

ただし、同じアプリケーションを標準のVMオプションで実行すると、正常に完了します。

Starting pollution
Terminating

なぜ最初の実行が失敗したのですか? 最も基本的なガベージコレクターでさえ、先ほど示した子供の遊びをクリーンアップできるようです

それでは、Epsilon GCの背後にある概念を見て、何が起こったのかを理解しましょう。

3. イプシロンGCのしくみ

Epsilonはノーオペレーションのガベージコレクターです。

JEP 318 「 [Epsilon]…メモリ割り当てを処理しますが、実際のメモリ再利用メカニズムは実装していません。 使用可能なJavaヒープが使い果たされると、JVMはシャットダウンします。 」

したがって、これは、アプリケーションがOutOfMemoryError。で終了した理由を説明しています。

しかし、それは疑問を投げかけます:なぜ私たちはゴミを収集しないガベージコレクターを持っている必要があるのですか?

使用可能なヒープで十分であることがわかっているため、JVMがリソースを使用してGCタスクを実行したくない場合があります。

そのような場合のいくつかの例(これも関連するJEPから):

  • 性能試験
  • メモリ圧力テスト
  • VMインターフェースのテスト
  • 非常に短命の仕事
  • ラストドロップレイテンシの改善
  • ラストドロップスループットの向上

4. 結論

この短い記事では、Java11で利用可能なno-opGCであるEpsilonについて学びました。 私たちはそれを使用することの意味について学び、それが便利かもしれないいくつかのケースをレビューしました。

いつものように、例はGitHubから入手できます。