Как обнаружить утечку памяти в Java?

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

Ответ

Для обнаружения утечек памяти в Java используются профилировщики и анализ дампов памяти.

Основные инструменты:

  • VisualVM (входит в JDK)
  • Eclipse MAT (Memory Analyzer Tool)
  • YourKit или JProfiler (коммерческие)

Практические шаги:

  1. Создание дампа памяти (heap dump) для анализа объектов.
    // Программное создание дампа
    HotSpotDiagnosticMXBean bean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
    bean.dumpHeap("heapdump.hprof", true);
  2. Мониторинг через JMX, отслеживая MemoryPoolMXBean на предмет постоянного роста.
  3. Использование ReferenceQueue с WeakReference/SoftReference для отслеживания утечек через ссылки.

Типичные источники утечек:

  • Статические коллекции (например, Map), куда добавляются, но не удаляются объекты.
  • Незакрытые ресурсы (InputStream, Connection, Session).
  • Слушатели событий (Listeners), от которых не отписываются.
  • Кэши без политики вытеснения (например, по времени или размеру).