Ошибка java.lang.OutOfMemoryError: превышен верхний предел GC

Я получаю это сообщение об ошибке, выполняя тесты JUnit:

java.lang.OutOfMemoryError: GC overhead limit exceeded

Я знаю, что такое OutOfMemoryError, но что означает верхний предел GC? Как я могу это решить?

Ответ 1

Это сообщение означает, что по какой-то причине сборщик мусора занимает слишком много времени (по умолчанию 98% всего времени процессора процесса) и восстанавливает очень мало памяти в каждом прогоне (по умолчанию 2% от кучи).

Это фактически означает, что ваша программа перестает делать какие-либо успехи и всегда работает только с мусорной коллекцией.

Чтобы ваше приложение не впитывало процессорное время без каких-либо действий, JVM выбрасывает этот Error, чтобы у вас была возможность диагностировать проблему.

Редкие случаи, когда я видел это, - это то, где какой-то код создавал тонны временных объектов и тонны объектов с низкой ссылкой в ​​среде с очень ограниченным объемом памяти.

Подробнее о в этой статье (в частности эта часть).

Ответ 2

GC генерирует это исключение, когда слишком много времени тратится на сбор мусора для слишком небольшого возврата, например. 98% времени процессора тратится на GC и восстанавливается менее 2% кучи.

Эта функция предназначена для того, чтобы приложения не работали в течение длительного периода времени, делая небольшие или никакие изменения, потому что куча слишком мала.

Вы можете отключить это с помощью опции командной строки -XX:-UseGCOverheadLimit

Подробнее здесь

EDIT: похоже, кто-то может набирать быстрее меня:)

Ответ 3

Если вы уверены, что в вашей программе нет утечки памяти, попробуйте:

  • Увеличьте размер кучи, например -Xmx1g.
  • Включить параллельный низкоуровневый сборщик -XX:+UseConcMarkSweepGC.
  • Повторно использовать существующие объекты, когда это возможно, чтобы сохранить некоторую память.

Если необходимо,

Ответ 4

Обычно это код. Вот простой пример:

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");
    }
}

Использование java 1.6.0_24-b07 На 32-разрядной версии Windows7.

java -Xloggc: gc.log GarbageCollector

Затем посмотрите на gc.log

  • Триггер 444 раза с использованием метода BAD
  • Триггер 666 раз с использованием метода WORSE
  • Триггер 354 раза с использованием метода BETTER.

Теперь предоставлено, это не лучший тест или лучший дизайн, но когда вы столкнулись с ситуацией, когда у вас нет выбора, кроме как реализовать такой цикл или при работе с существующим кодом, который ведет себя плохо, выбирая повторное использование объектов вместо создания новых они могут уменьшить количество сборов сборщика мусора в пути...

Ответ 5

Причина ошибки

Превышен лимит накладных расходов GC "означает, что сборщик мусора работает все время, а Java-программа продвигается очень медленно.

После сборки мусора, если Java-процесс тратит более чем приблизительно 98% своего времени на сборку мусора, и если он восстанавливает менее 2% кучи и выполняет до сих пор последние 5 (постоянная времени компиляции) подряд коллекций, затем выбрасывается java.lang.OutOfMemoryError

  1. Увеличьте размер кучи, если текущей кучи недостаточно.
  2. Если вы все еще получаете эту ошибку после увеличения кучи памяти, используйте инструменты профилирования памяти, такие как MAT (инструмент анализа памяти), Visual 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

Java 7 (JDK 7) сборка мусора и документация по G1

Сборка мусора Java G1 в производстве

Статья о технической сети Oracle для тонкой настройки GC

Ответ 6

Просто немного увеличьте размер кучи, установив эту опцию в

Запустить → Запустить конфигурации → Аргументы → Аргументы VM

-Xms1024M -Xmx2048M

Xms - для минимального предела

Xmx - для максимального предела

Ответ 7

Для меня сработали следующие шаги:

  1. Откройте файл eclipse.ini
  2. + Изменить

    -Xms40m
    -Xmx512m
    

    в

    -Xms512m
    -Xmx1024m
    
  3. Перезапустите Eclipse

Посмотреть здесь

Ответ 8

попробуйте это

откройте файл build.gradle

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

Ответ 9

Следующие работали для меня. Просто добавьте следующий фрагмент:

android {
        compileSdkVersion 25
        buildToolsVersion '25.0.1'

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

Ответ 10

увеличить javaMaxHeapsize в файле build.gradle(Module: app)

dexOptions {
    javaMaxHeapSize "1g"
}

to (Добавить эту строку в gradle)

 dexOptions {
        javaMaxHeapSize "4g"
    }

Ответ 11

Перезагрузка моего MacBook исправила эту проблему для меня.

Ответ 12

Вы также можете увеличить выделение памяти и размер кучи, добавив это в файл gradle.properties:

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

Это не должно быть 2048M и 32g, сделайте его таким большим, как вы хотите.

Ответ 13

Вам нужно увеличить размер памяти в 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**

Ответ 14

Я работаю в Android Studio и столкнулся с этой ошибкой при попытке создания подписанного APK для выпуска. Мне удалось создать и протестировать отладочную APK без проблем, но как только я захочу создать APK выпуска, процесс сборки будет работать в течение нескольких минут подряд, а затем окончательно завершится с помощью "Ошибка java.lang.OutOfMemoryError: GC превышение верхнего предела". Я увеличил размеры кучи как для VM, так и для компилятора Android DEX, но проблема не устранена. Наконец, после многих часов и кружек кофе выяснилось, что проблема была в моем файле buildGradle на уровне приложения. У меня был параметр minifyEnabled для типа сборки релиза, установленного на "false", и, следовательно, работа с продуктами Proguard по коду, который не прошел через процесс сжатия кода (см. https://developer.android.com/studio/build/shrink-code.html). Я изменил параметр "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
    }
}

//...

Ответ 15

Чтобы увеличить размер кучи в IntelliJ IDEA, следуйте приведенным ниже инструкциям. Это сработало для меня.

Для пользователей Windows,

Перейдите в место, где установлена среда IDE, и выполните поиск следующего.

idea64.exe.vmoptions

Отредактируйте файл и добавьте следующее.

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

Вот и все!

Ответ 16

Я использую apache-tomcat-8.5.37. Я сталкиваюсь с той же ошибкой

java.lang.outofmemoryerror: превышен предел накладных расходов gc

Я прочитал выше о решении поговорка

Увеличьте размер кучи, например -Xmx1g. Включите одновременный коллектор низкой паузы -XX: + UseConcMarkSweepGC. Повторно используйте существующие объекты, когда это возможно, чтобы сэкономить память. При необходимости проверку предела можно отключить, добавив параметр -XX: - UseGCOverheadLimit в командную строку.

Это решение сработало для кого-то? Нужен совет по устранению проблемы.

Ответ 17

Решено:
Просто добавьте
 org.gradle.jvmargs=-Xmx1024m
в
 gradle.properties
и если он не существует, создайте его.

Ответ 18

Описание размера кучи Java (xms, xmx, xmn)

-Xms size in bytes

Example : java -Xms32m

Устанавливает начальный размер кучи Java. Размер по умолчанию - 2097152 (2 МБ). Значения должны быть кратны и превышать 1024 байта (1 КБ). (Флаг -server увеличивает размер по умолчанию до 32M.)

-Xmn size in bytes

Example : java -Xmx2m

Устанавливает начальный размер кучи Java для поколения Eden. Значением по умолчанию является 640K. (Флаг -server увеличивает размер по умолчанию до 2M.)

-Xmx size in bytes

Example : java -Xmx2048m

Устанавливает максимальный размер, до которого может расти куча Java. Размер по умолчанию составляет 64M. (Флаг -server увеличивает размер по умолчанию до 128M.) Максимальный предел кучи составляет около 2 ГБ (2048 МБ).

Форматирование аргументов памяти Java (xms, xmx, xmn)

При настройке размера кучи Java вы должны указать аргумент памяти, используя одну из букв "m" или "M" для MB, или "g" или "G" для GB. Ваши настройки не будут работать, если вы укажете "МБ" или "ГБ". Допустимые аргументы выглядят так:

-Xms64m или -Xms64m -Xmx1G или -Xmx1G Можно также использовать 2048 МБ, чтобы указать 2 ГБ Кроме того, убедитесь, что вы просто используете целые числа при указании аргументов. Использование -Xmx512m является допустимым параметром, но -Xmx0.5g вызовет ошибку.

Эта ссылка может быть полезна для кого-то.

Ответ 19

В Netbeans может оказаться полезным создать максимальный размер кучи. Перейдите в Run = > Set Project Configuration = > Customize. В поле "Выполнить" всплывающее окно перейдите к опции VM, заполните -Xms2048m -Xmx2048m. Это может решить проблему размера кучи.