Рубрики
Без рубрики

OutOfMemoryError: Превышен лимит накладных расходов GC

Узнайте о превышении лимита накладных расходов OOM – GC, его причинах и способах его решения.

Автор оригинала: baeldung.

1. Обзор

Проще говоря, JVM заботится об освобождении памяти, когда объекты больше не используются; этот процесс называется сборкой мусора ( GC ).

Предел накладных расходов GC Превышен ошибка относится к семейству java.lang.OutOfMemoryError и является признаком исчерпания ресурса (памяти).

В этой краткой статье мы рассмотрим, что вызывает java.lang.OutOfMemoryError: Превышен предел накладных расходов GC ошибка и как ее можно решить.

2. Ошибка Превышения Предела Накладных расходов GC

OutOfMemoryError является подклассом java.lang.VirtualMachineError ; он выбрасывается JVM, когда он сталкивается с проблемой, связанной с использованием ресурсов. Более конкретно, ошибка возникает, когда JVM потратила слишком много времени на сборку мусора и смогла освободить очень мало места в куче.

Согласно документам Java, по умолчанию JVM настроен на выдачу этой ошибки, если процесс Java тратит более 98% своего времени на выполнение GC и когда при каждом запуске восстанавливается только менее 2% кучи. Другими словами, это означает, что наше приложение исчерпало почти всю доступную память, а сборщик мусора потратил слишком много времени на ее очистку и неоднократно терпел неудачу.

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

3. Ошибка в действии

Давайте посмотрим на фрагмент кода, который выдает java.lang.OutOfMemoryError: Превышен лимит накладных расходов GC.

Мы можем достичь этого, например, путем добавления пар ключ-значение в непрерывном цикле:

public class OutOfMemoryGCLimitExceed {
    public static void addRandomDataToMap() {
        Map dataMap = new HashMap<>();
        Random r = new Random();
        while (true) {
            dataMap.put(r.nextInt(), String.valueOf(r.nextInt()));
        }
    }
}

При вызове этого метода с аргументами JVM в виде -Xmx100m-XX:+UseParallelGC (размер кучи Java установлен на 100 МБ, а алгоритм GC-ParallelGC) мы получаем java.lang.OutOfMemoryError: Превышен предел накладных расходов GC ошибка. Чтобы лучше понять различные алгоритмы сборки мусора, мы можем проверить учебник Oracle Основы сборки мусора Java .

Мы получим java.lang.OutOfMemoryError: Предел накладных расходов GC превышен ошибка очень быстро, выполнив следующую команду из корня проекта :

mvn exec:exec

Следует также отметить, что в некоторых ситуациях мы можем столкнуться с ошибкой пространства кучи, прежде чем столкнемся с ошибкой GC, превышающей предел накладных расходов|/.

4. Решение проблемы Превышения предела накладных расходов GC

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

Необходимо ответить на следующие вопросы:

  • Какие объекты в приложении занимают большую часть кучи?
  • В каких частях исходного кода выделяются эти объекты?

Мы также можем использовать автоматизированные графические инструменты, такие как JConsole , которые помогают обнаруживать проблемы с производительностью в коде, включая java.lang.OutOfMemoryErrors.

Последним средством было бы увеличить размер кучи, изменив конфигурацию запуска JVM. Например, это дает 1 ГБ места в куче для приложения Java:

java -Xmx1024m com.xyz.TheClassName

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

5. Заключение

В этом уроке мы рассмотрели java.lang.OutOfMemoryError: превышен лимит накладных расходов GC и причины этого.

Как всегда, исходный код, связанный с этой статьей, можно найти на GitHub .