1. Обзор
Проще говоря, JVM заботится об освобождении памяти, когда объекты больше не используются; этот процесс называется сбором мусора (ссылка:/jvm-garbage-collectors[GC]).
Ошибка GC Overhead Limit Exceeded относится к семейству java.lang.OutOfMemoryError и указывает на исчерпание ресурса (памяти).
В этой быстрой статье мы рассмотрим причину ошибки java.lang.OutOfMemoryError: GC Overhead Limit Exceeded и ее решение.
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<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 МБ, а алгоритм GC равен ParallelGC), мы получаем ошибку java.lang.OutOfMemoryError: Ошибка превышения ограничения GC Exceeded_ . Чтобы лучше понять различные алгоритмы сбора мусора, мы можем обратиться к учебнику Oracle по Java Garbage Collection Basics учебнику.
Мы получим ошибку java.lang.OutOfMemoryError: GC Overhead Limit Exceeded очень быстро, выполнив следующую команду из корня project :
mvn exec:exec
Следует также отметить, что в некоторых ситуациях мы можем столкнуться с ошибкой пространства кучи, прежде чем встретим ошибку GC Overhead Limit Exceeded
4. Устранение ошибки превышения предельных значений ГХ
Идеальное решение - найти основную проблему с приложением, проверив код на наличие утечек памяти.
Необходимо ответить на следующие вопросы:
-
Какие объекты в приложении занимают большие порции
куча?
-
В каких частях исходного кода размещаются эти объекты?
Мы также можем использовать автоматизированные графические инструменты, такие как JConsole , которые помогают обнаруживать проблемы с производительностью в коде, включая java.lang. .OutOfMemoryErrors.
Последним средством будет увеличение размера кучи путем изменения конфигурации запуска JVM. Например, это дает 1 ГБ пространства кучи для приложения Java:
java -Xmx1024m com.xyz.TheClassName
Однако это не решит проблему, если в реальном коде приложения есть утечки памяти. Вместо этого мы просто отложим ошибку.
Поэтому более целесообразно пересмотреть использование памяти приложением.
5. Заключение
В этом руководстве мы рассмотрели __java.lang.OutOfMemoryError: Превышен предел накладных расходов GC и причины его возникновения
Как всегда, исходный код, связанный с этой статьей, можно найти на over на GitHub .