エラーjava.lang.OutOfMemoryError:GCオーバーヘッド制限を超えました


805

JUnitテストを実行すると、次のエラーメッセージが表示されます。

java.lang.OutOfMemoryError: GC overhead limit exceeded

私はそれが何であるかを知っていますOutOfMemoryErrorが、GCオーバーヘッド制限は何を意味しますか?どうすればこれを解決できますか?


16
これはとても興味深いですね。誰かがこれを生成するコードを投稿できたら嬉しいです。
Buhb

1
私は単にヒープの限界に近い、過度のメモリ使用につながる問題を見つけました。単純な解決策は、Javaエンジン(-Xmx)にヒープメモリを追加することですが、これは、アプリケーションが以前のヒープ制限が設定されていたのとまったく同じ量のメモリを必要とする場合にのみ役立ちます。
Mnementh 2009年

1
@Mnementh私はここで答えを出しましたが、それがstackoverflow.com/questions/11091516/…
lulu

16
@SimonKuang OutOfMemoryErrorヒープを増やすことが有効な解決策ではないシナリオがいくつかあることに注意してください。ネイティブスレッドの不足とperm gen(ヒープとは別)の不足は2つの例です。について過度に広い文を作成する場合は注意してくださいOutOfMemoryErrors。それらを引き起こす可能性のある予期せぬ多様な事柄があります。
Tim

3
どのように問題を解決しましたか?
Thorsten Niehues 2017年

回答:


764

このメッセージは、なんらかの理由でガベージコレクターが過度の時間(デフォルトではプロセスのすべてのCPU時間の98%)を消費し、各実行でメモリをほとんど回復しない(デフォルトではヒープの2%)ことを意味します。

これは事実上、プログラムが進行を停止し、常にガベージコレクションのみの実行でビジーであることを意味します。

アプリケーションが何もせずにCPU時間を消費するのを防ぐために、JVMはこれをスローしErrorて、問題を診断する機会を得ます。

これが発生するまれなケースは、一部のコードが、大量の一時オブジェクトと大量の弱参照オブジェクトを、非常にメモリに制約のある環境で作成していた場合です。

さまざまなJavaバージョンで利用可能で、この特定の問題に関するセクションが含まれているJava GCチューニングガイドを確認してください。


9
次のようにあなたの答えを要約することは正しいでしょうか:「これは、「Javaヒープ領域不足」エラーのようなものです。-Xmxでメモリを増やしてください。」?
Tim Cooper

58
@ティム:いいえ、それは正しくありません。メモリを増やすことで問題を軽減できますが、コードを調べて、その量のガベージが生成される理由と、コードが「メモリ不足」マークのすぐ下をスキミングする理由を確認する必要もあります。多くの場合、コードが壊れていることを示しています。
Joachim Sauer

8
おかげで、Oracleは実際にはデータ移行にそれほど優れていないようです。彼らはリンクを切断しました。
Joachim Sauer、

151
「ありがとう、オラクルは実際にはそれほど良くないようです」
Rob Grant

3
@Guus:複数のアプリケーションが同じJVMで実行されている場合、そうです、それらは簡単に相互に影響を及ぼします。どちらが誤動作しているかを判断するのは難しいでしょう。アプリケーションを個別のJVMに分離することは、最も簡単なソリューションかもしれません。
Joachim Sauer、

215

Oracleの記事「Java SE 6 HotSpot [tm] Virtual Machine Garbage Collection Tuning」からの引用:

過剰なGC時間とOutOfMemoryError

ガベージコレクションに費やされている時間が多すぎる場合、パラレルコレクターはOutOfMemoryErrorをスローします。ガベージコレクションに費やされた合計時間が98%を超え、回復されたヒープが2%未満の場合、OutOfMemoryErrorがスローされます。この機能は、ヒープが小さすぎるため、ほとんどまたはまったく進行せずに、アプリケーションが長期間実行されないようにするために設計されています。必要に応じ-XX:-UseGCOverheadLimitて、コマンドラインにオプションを追加して、この機能を無効にすることができます。

編集:誰かが私より速くタイプできるように見えます:)


87
「これをオフにすることができます...」しかし、OPはおそらくこれを行うべきではありません。
スティーブンC

2
「-XX」と「-Xmx」の違いを教えてください。「-Xmx」オプションを使用してオフにすることもできました。
Susheel Javadi、

19
ここで非常に古いコメントに返信しますが、... @Bart -XX:いくつかのコマンドラインオプションの先頭は、このオプションがVM固有で非常に不安定であることを示すフラグです(将来のバージョンでは予告なしに変更される可能性があります)。いずれの場合も、-XX:-UseGCOverheadLimitフラグはVMにGCオーバーヘッド制限チェックを無効にするように指示しますが(実際には「オフにする」)、-Xmxコマンドは単にヒープを増やしただけです。後者の場合、GCオーバーヘッドチェックはまだ実行されていましたが、より大きなヒープがあなたのケースの GCスラッシング問題を解決したように聞こえます(これは常に役立つとは限りません)。
Andrzej Doyle

1
私のアプリケーション(Talendで大きなExcelファイルを読み取る)ではこれは機能せず、他のユーザーからの説明で理由を理解しています。これはエラーを無効にするだけですが、問題は解決せず、アプリケーションはほとんどの時間をGCの処理に費やします。サーバーには十分なRAMがあったため、Vitaliiの提案を使用してヒープサイズを増やしました。
RobbZ 2016年

アプリケーションがデータを集中的に使用する場合、最終的にこのエラーが発生します。メモリをクリアし、データリークを回避するのが最善の方法ですが、少し時間がかかります。
Pievis

89

プログラムにメモリリークがないことが確かな場合は、次のことを試してください。

  1. たとえば、ヒープサイズを増やします-Xmx1g
  2. 同時ローポーズコレクターを有効にし-XX:+UseConcMarkSweepGCます。
  3. 可能な場合は既存のオブジェクトを再利用して、メモリを節約します。

必要に応じて、コマンドラインにオプションを追加することで、制限チェックを無効にすることができます-XX:-UseGCOverheadLimit


9
3番目のアドバイスに同意しません。既存のオブジェクトを再利用してもメモリは節約されません(古いオブジェクトをリークしないでメモリを節約してください:-)さらに、「既存のオブジェクトを再利用する」はGCの負荷を軽減するための方法でした。しかし、それは
必ずしも

@mcoolive:やや工夫された例については、以下のstackoverflow.com/a/5640498/4178262に回答するコメントを参照してください。Listループ内にオブジェクトを作成すると、GCが22回ではなく39回呼び出されていました。
マークスチュワート

45

通常はコードです。以下に簡単な例を示します。

import java.util.*;

public class GarbageCollector {

    public static void main(String... args) {

        System.out.printf("Testing...%n");
        List<Double> list = new ArrayList<Double>();
        for (int outer = 0; outer < 10000; outer++) {

            // list = new ArrayList<Double>(10000); // BAD
            // list = new ArrayList<Double>(); // WORSE
            list.clear(); // BETTER

            for (int inner = 0; inner < 10000; inner++) {
                list.add(Math.random());
            }

            if (outer % 1000 == 0) {
                System.out.printf("Outer loop at %d%n", outer);
            }

        }
        System.out.printf("Done.%n");
    }
}

Windows 7 32ビットでのJava 1.6.0_24-b07の使用。

java -Xloggc:gc.log GarbageCollector

次に見て gc.log

  • BADメソッドを使用して444回トリガー
  • WORSEメソッドを使用して666回トリガー
  • BETTERメソッドを使用して354回トリガー

当然のことながら、これは最良のテストでも最良の設計でもありませんが、そのようなループを実装せざるを得ない状況に直面した場合や、動作が悪い既存のコードを処理する場合、新しいものを作成する代わりにオブジェクトを再利用することを選択すると、ガベージコレクターが邪魔する回数...


12
明確にしてください:「トリガーされたn回」と言う場合、それは通常のGCがn回発生したことを意味しますか、それともOPによって報告された「GCオーバーヘッド制限を超えました」エラーがn回発生したことを意味しますか?
Jon Schneider

私はjava 1.8.0_91を使用してテストしたところ、エラー/例外は発生しませんでした。「n回トリガー」は、gc.logファイル内の行数をカウントアップしたものです。私のテストでは、全体的に表示される時間ははるかに少なくなっていますが、BETTERの「トリガー」時間は最も少なく、現在、BADはWORSTより「悪い」です。私のカウント:BAD:26、さらに悪い:22、BETTER 21
マーク・スチュワート

私はちょうど私が定義する「WORST_YET」修正を追加List<Double> listして、外側のループの代わりに、前に外側のループを、そして39回のガベージコレクションをトリガ。
マークスチュワート

36

Java [8] Platform、Standard Editionトラブルシューティングガイドによるエラーの原因:(強調と改行が追加されました)

[...]「GCオーバーヘッド制限を超えました」は、ガベージコレクターが常に実行されていて、Javaプログラムの進行が非常に遅いことを示しています。

ガベージコレクションの後、Javaプロセスがガベージコレクションに費やす時間の約98%以上を費やしていて、ヒープの2%未満しか回復せず、これまでに最後の5(コンパイル時定数)ガベージを実行している場合コレクション、次にjava.lang.OutOfMemoryErrorスローされます。[...]

  1. 現在のヒープが十分でない場合は、ヒープサイズを増やします
  2. あなたはまだヒープメモリ、使用メモリ増加した後に、このエラーが発生した場合プロファイリングツールのようなMAT(メモリー・アナライザツール)、 ビジュアルVMなどと修正メモリリークを。
  3. JDKバージョンを最新バージョン(1.8.x)または少なくとも1.7.xにアップグレードし、G1GCアルゴリズムを使用します。。G1 GCのスループット目標は、90%のアプリケーション時間と10%のガベージコレクション時間です。
  4. - Xms1g -Xmx2gでヒープメモリを設定する以外に、

    -XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m  
    -XX:ParallelGCThreads=n -XX:ConcGCThreads=n

G1GCに関するいくつかの関連質問をご覧ください


29

このオプションを次のように設定して、ヒープサイズを少し増やします。

実行→実行構成→引数→VM引数

-Xms1024M -Xmx2048M

Xms-最小制限

Xmx-最大制限


2
Androidアプリにはargumentsタブがありません...これを実現するにはどうすればよいですか?
Blaze Tama

3
その答えはどのツールですか?それはEclipseの質問ではありませんでした。
Michael Piefel 16

3
「最低限度」はありません。-Xmsは初期サイズです。
Diego Queiroz 2017年

1
設定できる最大制限の最大値はいくつですか?
JPerk 2017年

14

私にとっては、次の手順が機能しました:

  1. eclipse.iniファイルを開く
  2. 変化する

    -Xms40m
    -Xmx512m

    -Xms512m
    -Xmx1024m
  3. Eclipseを再起動します

こちらをご覧ください


この問題を解決する最も簡単な方法。おかげで:)
ハムザ2015年

1
jdevのeclipse.iniファイル?
Abhinaba Basu 2015

これに設定を変更しても問題は未解決。
zionpi

1
OPはEclipseの質問をしませんでした。
Michael Piefel 16

1
この「答え」は上記の質問には答えません。
Freitags 2017

13

これを試して

build.gradleファイルを 開く

  android {
        dexOptions {
           javaMaxHeapSize = "4g"
        }
   }

シミュレーターに最適です。これが実際のデバイスにどのように影響するか考えていますか?つまり、これは良いアイデアですか、それとも問題を隠していますか?ありがとう。
ジョシュア・ピンター2017

11

以下は私のために働いた。次のスニペットを追加するだけです。

android {
        compileSdkVersion 25
        buildToolsVersion '25.0.1'

defaultConfig {
        applicationId "yourpackage"
        minSdkVersion 10
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
dexOptions {
        javaMaxHeapSize "4g"
    }
}

はい、Gradleを使用する場合:)
Alex

4
これが彼の一般的な質問に対する解決策であるとどうして考えられますか?ヒープサイズを4gに設定します。これは、Android facepalmのGradle構成では完全に任意です
ジュリアンL.

7

build.gradle(Module:app)ファイルのjavaMaxHeapsizeを増やします

dexOptions {
    javaMaxHeapSize "1g"
}

へ(この行をgradleに追加)

 dexOptions {
        javaMaxHeapSize "4g"
    }

3

Javaヒープサイズの説明(xms、xmx、xmn)

-Xms size in bytes

Example : java -Xms32m

Javaヒープの初期サイズを設定します。デフォルトのサイズは2097152(2MB)です。値は、1024バイト(1KB)の倍数以上でなければなりません。(-serverフラグは、デフォルトのサイズを32Mに増やします。)

-Xmn size in bytes

Example : java -Xmx2m

Eden世代の初期Javaヒープサイズを設定します。デフォルト値は640Kです。(-serverフラグは、デフォルトのサイズを2Mに増やします。)

-Xmx size in bytes

Example : java -Xmx2048m

Javaヒープが拡張できる最大サイズを設定します。デフォルトのサイズは64Mです。(-serverフラグはデフォルトのサイズを128Mに増やします。)最大ヒープ制限は約2 GB(2048MB)です。

Javaメモリ引数(xms、xmx、xmn)のフォーマット

Javaヒープサイズを設定するときは、MBの場合は「m」または「M」、GBの場合は「g」または「G」のいずれかの文字を使用してメモリ引数を指定する必要があります。「MB」または「GB」を指定した場合、設定は機能しません。有効な引数は次のようになります。

-Xms64mまたは-Xms64M -Xmx1gまたは-Xmx1G 2048MBを使用して2GBを指定することもできますまた、引数を指定するときは、整数のみを使用するようにしてください。-Xmx512mの使用は有効なオプションですが、-Xmx0.5gを使用するとエラーが発生します。

この参照は、誰かに役立つ場合があります。


2

これをgradle.propertiesファイルに追加して、メモリ割り当てとヒープサイズを増やすこともできます。

org.gradle.jvmargs=-Xmx2048M -XX\:MaxHeapSize\=32g

2048Mや32gでなくてもかまいません。


2

解決済み:
追加するだけ
org.gradle.jvmargs=-Xmx1024m

gradle.properties
、存在しない場合は作成します。


0

Android Studioで作業していて、リリース用の署名済みAPKを生成しようとしたときにこのエラーが発生しました。問題なくデバッグAPKをビルドしてテストすることができましたが、リリースAPKをビルドしたいとすぐに、ビルドプロセスが最後まで数分間実行され、最後に「エラーjava.lang.OutOfMemoryError:GCで終了しました。オーバーヘッド制限を超えました。」VMとAndroid DEXコンパイラの両方のヒープサイズを増やしましたが、問題は解決しませんでした。最後に、何時間もコーヒーを飲み続けた後、問題はアプリレベルの「build.gradle」ファイルにあることがわかりました-リリースビルドタイプの「minifyEnabled」パラメーターを「false」に設定し、その結果Proguardを実行しましたコード圧縮プロセスを経ていないコード(https://developer.android。)。「minifyEnabled」パラメーターを「true」に変更すると、リリースビルドが夢のように実行されました:)

つまり、アプリレベルの「build.gradle」ファイルを/// ...から変更する必要がありました。

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.sign_config_release
    }
    debug {
        debuggable true
        signingConfig signingConfigs.sign_config_debug
    }
}

//...

    //...

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.sign_config_release
    }
    debug {
        debuggable true
        signingConfig signingConfigs.sign_config_debug
    }
}

//...

0

IntelliJ IDEAでヒープサイズを増やすには、次の手順に従います。それは私のために働いた。

Windowsユーザーの場合

IDEがインストールされている場所に移動し、以下を検索します。

idea64.exe.vmoptions

ファイルを編集して、以下を追加します。

-Xms512m
-Xmx2024m
-XX:MaxPermSize=700m
-XX:ReservedCodeCacheSize=480m

それだ !!


0

この画像を参照してサーバー設定を変更して、黄色で強調表示されているプロセス変更を処理するためのメモリサイズを増やすことができます。

set _java_opts -Xmx2g
プログラムの複雑さに応じて、cmd-> 2g(2gigabytes)を開いてjavaヒープを変更することもできます

定数の少ない変数と一時的な変数を使用してみてください

ここに画像の説明を入力してください


-1

Jdeveloperでメモリー・サイズを増やす必要があるため、setDomainEnv.cmdに移動します

set WLS_HOME=%WL_HOME%\server    
set XMS_SUN_64BIT=**256**
set XMS_SUN_32BIT=**256**
set XMX_SUN_64BIT=**3072**
set XMX_SUN_32BIT=**3072**
set XMS_JROCKIT_64BIT=**256**
set XMS_JROCKIT_32BIT=**256**
set XMX_JROCKIT_64BIT=**1024**
set XMX_JROCKIT_32BIT=**1024**

if "%JAVA_VENDOR%"=="Sun" (
    set WLS_MEM_ARGS_64BIT=**-Xms256m -Xmx512m**
    set WLS_MEM_ARGS_32BIT=**-Xms256m -Xmx512m**
) else (
    set WLS_MEM_ARGS_64BIT=**-Xms512m -Xmx512m**
    set WLS_MEM_ARGS_32BIT=**-Xms512m -Xmx512m**
)

そして

set MEM_PERM_SIZE_64BIT=-XX:PermSize=**256m**
set MEM_PERM_SIZE_32BIT=-XX:PermSize=**256m**

if "%JAVA_USE_64BIT%"=="true" (
    set MEM_PERM_SIZE=%MEM_PERM_SIZE_64BIT%
) else (
    set MEM_PERM_SIZE=%MEM_PERM_SIZE_32BIT%
)

set MEM_MAX_PERM_SIZE_64BIT=-XX:MaxPermSize=**1024m**
set MEM_MAX_PERM_SIZE_32BIT=-XX:MaxPermSize=**1024m**

4
これらの設定は、ローカルIDEにのみ固有です。これは、製品環境では機能しません。
Feng

-1

Netbeansでは、最大ヒープサイズを設計すると役立つ場合があります。[ 実行] => [ プロジェクト構成の設定] => [ カスタマイズ]に移動します。で実行そのポップアップウィンドウの、に行くVMオプション、中塗り-Xms2048m -Xmx2048m。ヒープサイズの問題を解決できます。



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.