OutOfMemoryError:GCオーバーヘッド制限を超えました
1. 概要
簡単に言うと、JVMは、オブジェクトが使用されなくなったときにメモリを解放します。 このプロセスは、ガベージコレクション( GC )と呼ばれます。
GCオーバーヘッド制限超過エラーは、 java .lang.OutOfMemoryError ファミリのエラーであり、リソース(メモリ)の枯渇を示しています。
このクイックチュートリアルでは、 java .lang.OutOfMemoryError:GC Overhead Limit Exceeded エラーの原因と、その解決方法について説明します。
2. GCオーバーヘッド制限超過エラー
OutOfMemoryError は、 java.lang.VirtualMachineErrorのサブクラスです。 これは、リソースの利用に関連する問題が発生したときにJVMによってスローされます。 より具体的には、エラーは、JVMがガベージコレクションの実行に多くの時間を費やし、ごくわずかなヒープスペースしか再利用できなかった場合に発生します。
Javaドキュメントによると、デフォルトでは、JavaプロセスがGCの実行に98 % o f以上を費やし、各実行でヒープが回復されるのが2 % o f未満の場合、JVMはこのエラーをスローするように構成されています。 つまり、これは、アプリケーションが使用可能なメモリのほぼすべてを使い果たし、ガベージコレクターがそれをクリーンアップするのに時間がかかりすぎて、繰り返し失敗したことを意味します。
この状況では、ユーザーはアプリケーションの極端な速度低下を経験します。 通常はミリ秒単位で完了する特定の操作は、完了するまでに時間がかかります。 これは、CPUがガベージコレクションに全容量を使用しているため、他のタスクを実行できないためです。
3. 動作中のエラー
java .lang.OutOfMemoryError:GC Overhead LimitExceededをスローするコードを見てみましょう。
これは、たとえば、終了していないループにキーと値のペアを追加することで実現できます。
public class OutOfMemoryGCLimitExceed {
public static void addRandomDataToMap() {
Map<Integer, String> dataMap = new HashMap<>();
Random r = new Random();
while (true) {
dataMap.put(r.nextInt(), String.valueOf(r.nextInt()));
}
}
}
このメソッドが呼び出され、JVM引数が -Xmx100m -XX:+ UseParallelGC (Javaヒープサイズが100 MBに設定され、GCアルゴリズムがParallelGC)の場合、java .lang.OutOfMemoryError:GCオーバーヘッド制限がエラーを超えました。 さまざまなガベージコレクションアルゴリズムをよりよく理解するには、OracleのJavaガベージコレクションの基本チュートリアルを確認してください。
java .lang.OutOfMemoryError:プロジェクトのルートから次のコマンドを実行すると、GCオーバーヘッド制限がエラーをすぐに超えました。
mvn exec:exec
また、状況によっては、 GC Overhead LimitExceededエラーが発生する前にヒープスペースエラーが発生する場合があることにも注意してください。
4. GCオーバーヘッド制限超過エラーの解決
理想的な解決策は、メモリリークがないかコードを調べて、アプリケーションの根本的な問題を見つけることです。
これらの質問に対処する必要があります。
- ヒープの大部分を占めるアプリケーション内のオブジェクトは何ですか?
- これらのオブジェクトはソースコードのどの部分に割り当てられていますか?
JConsole などの自動グラフィカルツールを使用することもできます。これは、 java.lang.OutOfMemoryErrorsなどのコードのパフォーマンスの問題を検出するのに役立ちます。
最後の手段は、JVMの起動構成を変更してヒープサイズを増やすことです。
たとえば、これにより、Javaアプリケーション用に1GBのヒープスペースが提供されます。
java -Xmx1024m com.xyz.TheClassName
ただし、実際のアプリケーションコードにメモリリークがある場合、これでは問題は解決しません。 代わりに、エラーを延期します。 したがって、アプリケーションのメモリ使用量を徹底的に再評価することをお勧めします。
5. 結論
この記事では、 java .lang.OutOfMemoryError:GC Overhead LimitExceededとその背後にある理由を調べました。
いつものように、この記事に関連するソースコードはGitHubのにあります。