Что такое OutOfMemoryError в Java?

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

Ответ

OutOfMemoryError — это неконтролируемое исключение (java.lang.Error), возникающее, когда виртуальная машина Java (JVM) не может выделить память в куче (heap) для создания нового объекта, и сборщик мусора (Garbage Collector) не может освободить достаточное её количество.

Основные причины:

  • Утечки памяти: Объекты остаются достижимыми (например, через статические коллекции), хотя логически уже не нужны.
  • Недостаточный размер heap: Параметры -Xmx (максимальный размер) заданы слишком низко для рабочей нагрузки.
  • Большие/неограниченные структуры данных: Постоянный рост кэшей или коллекций без очистки.

Пример, вызывающий ошибку:

import java.util.ArrayList;
import java.util.List;

public class OOMExample {
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        while (true) {
            // Бесконечно добавляем массив в 1 МБ
            list.add(new byte[1024 * 1024]);
        }
    }
}

Как диагностировать и предотвратить:

  1. Настройте размер heap: Укажите адекватные -Xms (начальный размер) и -Xmx через аргументы JVM.
  2. Анализируйте дамп памяти: Используйте -XX:+HeapDumpOnOutOfMemoryError, а затем анализируйте файл .hprof в Eclipse MAT или VisualVM.
  3. Используйте слабые ссылки: Для кэшей применяйте WeakHashMap или SoftReference, чтобы GC мог их очистить.
  4. Профилируйте приложение: Следите за потреблением памяти с помощью Java Flight Recorder (JFR) или JMX.