Что происходит при переполнении кучи (Heap) в Java?

«Что происходит при переполнении кучи (Heap) в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

JVM выбрасывает java.lang.OutOfMemoryError с сообщением "Java heap space". Это критическая ошибка, означающая, что приложение исчерпало всю выделенную память под объекты, и сборщик мусора (GC) не может освободить достаточное её количество.

Пример, приводящий к ошибке:

List<byte[]> leak = new ArrayList<>();
while (true) {
    leak.add(new byte[10_000_000]); // Постоянное выделение памяти
}

Последствия:

  1. Поток, в котором произошла ошибка, завершается.
  2. Если ошибка не обработана и возникает в критическом потоке (например, main), приложение аварийно останавливается.
  3. Обработать OutOfMemoryError можно, но это сложно и обычно не рекомендуется.

Как избежать и диагностировать:

  • Увеличить кучу: Задать больший лимит через JVM-флаги -Xmx4g (максимум 4 ГБ).
  • Найти утечку: Использовать профилировщики (VisualVM, YourKit, JProfiler) для анализа heap dump.
  • Практики кодирования:
    • Корректно закрывать ресурсы (использовать try-with-resources).
    • Избегать долгоживущих ссылок на временные объекты в коллекциях.
    • Для кэшей использовать WeakReference или специализированные библиотеки (Guava, Caffeine).