Gc overhead limit exceeded android studio

java.lang.OutOfMemoryError:
GC overhead limit exceeded

Java runtime environment contains a built-in Garbage Collection (GC) process. In many other programming languages, the developers need to manually allocate and free memory regions so that the freed memory can be reused.

Java applications on the other hand only need to allocate memory. Whenever a particular space in memory is no longer used, a separate process called Garbage Collection clears the memory for them. How the GC detects that a particular part of memory is explained in more detail in the Garbage Collection Handbook, but you can trust the GC to do its job well.

The java.lang.OutOfMemoryError: GC overhead limit exceeded error is displayed when your application has exhausted pretty much all the available memory and GC has repeatedly failed to clean it.

The java.lang.OutOfMemoryError: GC overhead limit exceeded error is the JVM’s way of signalling that your application spends too much time doing garbage collection with too little result. By default the JVM is configured to throw this error if it spends more than 98% of the total time doing GC and when after the GC only less than 2% of the heap is recovered.

What would happen if this GC overhead limit would not exist? Note that the java.lang.OutOfMemoryError: GC overhead limit exceeded error is only thrown when 2% of the memory is freed after several GC cycles. This means that the small amount of heap the GC is able to clean will likely be quickly filled again, forcing the GC to restart the cleaning process again. This forms a vicious cycle where the CPU is 100% busy with GC and no actual work can be done. End users of the application face extreme slowdowns – operations which normally complete in milliseconds take minutes to finish.

So the “java.lang.OutOfMemoryError: GC overhead limit exceeded” message is a pretty nice example of a fail fast principle in action.

In the following example we create a “GC overhead limit exceeded” error by initializing a Map and adding key-value pairs into the map in an unterminated loop:

As you might guess this cannot end well. And, indeed, when we launch the above program with:

we soon face the java.lang.OutOfMemoryError: GC overhead limit exceeded message. But the above example is tricky. When launched with different Java heap size or a different GC algorithm, my Mac OS X 10.9.2 with Hotspot 1.7.0_45 will choose to die differently. For example, when I run the program with smaller Java heap size like this:

the application will die with a more common java.lang.OutOfMemoryError: Java heap space message that is thrown on Map resize. And when I run it with other garbage collection algorithms besides ParallelGC, such as -XX:+UseConcMarkSweepGC or -XX:+UseG1GC, the error is caught by the default exception handler and is without stacktrace as the heap is exhausted to the extent where the stacktrace cannot even be filled on Exception creation.

These variations are truly good examples that demonstrate that in resource-constrained situations you cannot predict the way your application is going to die so do not base your expectations on a specific sequence of actions to be completed.

As a tongue-in-cheek solution, if you just wished to get rid of the “java.lang.OutOfMemoryError: GC overhead limit exceeded” message, adding the following to your startup scripts would achieve just that:

I would strongly suggest NOT to use this option though – instead of fixing the problem you just postpone the inevitable: the application running out of memory and needing to be fixed. Specifying this option will just mask the original java.lang.OutOfMemoryError: GC overhead limit exceeded error with a more familiar message java.lang.OutOfMemoryError: Java heap space.

On a more serious note – sometimes the GC overhead limit error is triggered because the amount of heap you have allocated to your JVM is just not enough to accommodate the needs of your applications running on that JVM. In that case, you should just allocate more heap – see at the end of this chapter for how to achieve that.

Читайте также:  Learning android with java

In many cases however, providing more Java heap space will not solve the problem. For example, if your application contains a memory leak, adding more heap will just postpone the java.lang.OutOfMemoryError: Java heap space error. Additionally, increasing the amount of Java heap space also tends to increase the length of GC pauses affecting your application’s throughput or latency.

If you wish to solve the underlying problem with the Java heap space instead of masking the symptoms, you need to figure out which part of your code is responsible for allocating the most memory. In other words, you need to answer these questions:

  1. Which objects occupy large portions of heap
  2. where these objects are being allocated in source code

At this point, make sure to clear a couple of days in your calendar (or – see an automated way below the bullet list). Here is a rough process outline that will help you answer the above questions:

  • Get clearance for acquiring a heap dump from your JVM-to-troubleshoot. “Dumps” are basically snapshots of heap contents that you can analyze, and contain everything that the application kept in memory at the time of the dump. Including passwords, credit card numbers etc.
  • Instruct your JVM to dump the contents of its heap memory into a file. Be prepared to get a few dumps, as when taken at a wrong time, heap dumps contain a significant amount of noise and can be practically useless. On the other hand, every heap dump “freezes” the JVM entirely, so don’t take too many of them or your end users start swearing.
  • Find a machine that can load the dump. When your JVM-to-troubleshoot uses for example 8GB of heap, you need a machine with more than 8GB to be able to analyze heap contents. Fire up dump analysis software (we recommend Eclipse MAT, but there are also equally good alternatives available).
  • Detect the paths to GC roots of the biggest consumers of heap. We have covered this activity in a separate post here. Don’t worry, it will feel cumbersome at first, but you’ll get better after spending a few days digging.
  • Next, you need to figure out where in your source code the potentially hazardous large amount of objects is being allocated. If you have good knowledge of your application’s source code you’ll hopefully be able to do this in a couple searches. When you have less luck, you will need some energy drinks to assist.

Alternatively, we suggest Plumbr, the only Java monitoring solution with automatic root cause detection. Among other performance problems it catches all java.lang.OutOfMemoryErrors and automatically hands you the information about the most memory-hungry data structres. It takes care of gathering the necessary data behind the scenes – this includes the relevant data about heap usage (only the object layout graph, no actual data), and also some data that you can’t even find in a heap dump. It also does the necessary data processing for you – on the fly, as soon as the JVM encounters an java.lang.OutOfMemoryError. Here is an example java.lang.OutOfMemoryError incident alert from Plumbr:

Without any additional tooling or analysis you can see:

  • Which objects are consuming the most memory (271 com.example.map.impl.PartitionContainer instances consume 173MB out of 248MB total heap)
  • Where these objects were allocated (most of them allocated in the MetricManagerImpl class, line 304)
  • What is currently referencing these objects (the full reference chain up to GC root)

Equipped with this information you can zoom in to the underlying root cause and make sure the data structures are trimmed down to the levels where they would fit nicely into your memory pools.

However, when your conclusion from memory analysis or from reading the Plumbr report are that memory use is legal and there is nothing to change in the source code, you need to allow your JVM more Java heap space to run properly. In this case, alter your JVM launch configuration and add (or increase the value if present) just one parameter in your startup scripts:

Читайте также:  Медиаплеер для андроид apk

In the above example the Java process is given 1GB of heap. Modify the value as best fits to your JVM. However, if the result is that your JVM still dies with OutOfMemoryError, you might still not be able to avoid the manual or Plumbr-assisted analysis described above.

Источник

Android Studio JAR файл, вызывающий превышение лимита GC overhead

Я использую Android Studio на OS X. Я получаю это сообщение об ошибке:

FAILURE: сбой сборки с исключением.

Что пошло не так: Выполнение выполнено для задачи ‘: app: preDexDebug’. com.android.ide.common.internal.LoggedErrorException: Не удалось запустить команду: /Приложения/Android Studio.app/sdk/build-tools/android-4.4W/dx —dex —output/Users/alex/AndroidStudioProjects/SilentSMS/app/build/intermediates/pre-dexed/debug/android-4.3 _r2.1-f22bbff4d1017230e169a4844a9c2195f13060d2.jar/Users/alex/AndroidStudioProjects/SilentSMS/app/libs/android-4.3_r2.1.jar

Код ошибки: 3 Выход:

Я использую эту библиотеку:

Я вытащил JAR файл и добавил его в свой проект. Проект, который я пытаюсь построить, это:

Я понимаю, это потому, что мои значения xms и xmx слишком низки. Я увеличил их:

/Приложения/Android Studio.app/bin/idea.vmoptions, чтобы теперь он говорил:

Однако я все еще получаю ошибку. Что это может быть вызвано? Помимо приложения silentSMS, являющегося проектом Eclipse, и я портирую код на Android Studio, я ничего не изменил. С точки зрения ошибок Android Studio — это не так, и все остальное выглядит нормально.

ОТВЕТЫ

Ответ 1

Я думаю, что есть отдельный способ повысить предел кучи операции dexing. Добавьте это в свою android закрытие в файле build.gradle :

и посмотрите, помогает ли это.

Ответ 2

В моем случае увеличение размера кучи выглядит следующим образом:

Использование Android Studio 1.1.0

Поместите вышеуказанный код в файл Build.gradle.

Ответ 3

Эта новая проблема вызвана последней версией Android.

Перейдите в корневую папку проекта, откройте gradle.properties и добавьте следующие параметры:

Затем добавьте эти изменения в свой build.gradle файл:

Ответ 4

Я отключу свой Instant Run:

Предпочтение меню → Сборка → Мгновенный запуск «Включить мгновенный запуск до горячего кода»

Я думаю, что это Instant Run, который делает сборку медленной и создает файл pidXXX.hprof большого размера, из-за чего превышается верхний предел AndroidStudio gc.

(Мой SDK устройства — 19.)

Ответ 5

Я принудительно закрыл все Java.exe из taskmanger, перезапустил Android Studio и работал у меня

Ответ 6

Для меня не ответы, которые я работал, я видел здесь. Я догадался, что работа процессора крайне затрудняет работу компьютера. После того, как я закрыл программы, которые потребляют большое количество процессора (например, хром) и охлаждая мой ноутбук, проблема исчезла.

Для справки: у меня был процессор с 96% -97% и использование памяти более 2 000 000 К с помощью процесса java.exe(который был фактически связан с gradle).

Ответ 7

Добавьте это в файл build.gradle

Ответ 8

Я использую Android Studio 3.4 и единственное, что мне build.gradle удалить следующие строки из моего файла build.gradle :

Android Studio 3.4 использует R8 в full mode и не совместима напрямую с Proguard

Ответ 9

в моем случае я редактирую свой gradle.properties :

примечание: если вы включите minifyEnabled true :

Источник

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

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

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

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

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

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

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

Ознакомьтесь с руководством по настройке Java GC, которое доступно для различных версий Java и содержит разделы об этой конкретной проблеме:

  • Руководство по настройке Java 11 имеет специальные разделы по избыточному сборщику мусора для различных сборщиков мусора:
    • для параллельного коллектора
    • для коллекторов Concurrent Mark Sweep (CMS)
    • нет никакого упоминания об этом конкретном состоянии ошибки для сборщика мусора (G1).
  • Руководство по настройке Java 8 и его раздел GC
  • Руководство по настройке Java 6 и его раздел GC .

Чрезмерное время GC и OutOfMemoryError

Параллельный сборщик сгенерирует OutOfMemoryError, если на сборку мусора уходит слишком много времени: если на сборку мусора уходит более 98% общего времени и восстанавливается менее 2% кучи, генерируется ошибка OutOfMemoryError. Эта функция предназначена для предотвращения запуска приложений в течение длительного периода времени при небольшом прогрессе или его отсутствии, поскольку куча слишком мала. При необходимости эту функцию можно отключить, добавив эту опцию -XX:-UseGCOverheadLimit в командную строку.

Читайте также:  Почему андроид не видеть всю память микро сд

РЕДАКТИРОВАТЬ: похоже, кто-то может печатать быстрее, чем я 🙂

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

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

При необходимости проверку лимита можно отключить, добавив эту опцию -XX:-UseGCOverheadLimit в командную строку.

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

Использование Java 1.6.0_24-b07 в 32-разрядной версии Windows 7.

Тогда посмотрите на gc.log

  • Сработало 444 раза, используя метод BAD
  • Сработало 666 раз, используя метод WORSE
  • Сработал 354 раза, используя метод ЛУЧШЕ

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

Причина ошибки в соответствии с платформой Java [8], Руководство по устранению неполадок Standard Edition : (выделение и разрывы строк добавлены)

[. ] «Превышен лимит накладных расходов 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% времени сбора мусора

Помимо установки кучи памяти с помощью — Xms1g -Xmx2g , попробуйте

Посмотрите еще несколько связанных вопросов, касающихся G1GC

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

Выполнить → Выполнить настройки → Аргументы → Аргументы виртуальной машины

Xms — для минимального лимита

Xmx — для максимального лимита

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

    Открыть eclipse.ini файл

открыть build.gradle файл

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

увеличьте javaMaxHeapsize в вашем файле build.gradle (модуль: приложение)

(добавить эту строку в Gradle)

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

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

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

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

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

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

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

Источник

Оцените статью