В Java: считается ли объект, который долго не используется, кандидатом на сборку мусора?

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

Ответ

Нет, время неиспользования объекта напрямую не влияет на сборку мусора (GC).

Ключевой критерий GC — достижимость объекта. Объект будет удален, если на него нет ни одной активной ссылки из так называемых "GC Roots" (потоки, статические поля, локальные переменные в стеке и т.д.).

Почему долгое неиспользование ≠ удаление?

  • Статические поля: Объект, на который ссылается статическое поле, будет жить, пока загружен его класс (ClassLoader).
  • Кэши/пулы: Объекты в кэшах (например, HashMap) удерживаются сильными ссылками и не собираются, даже если не используются.
  • Утечки памяти: Объект может быть достижим через незаметные ссылки (например, в коллекции слушателей событий).

Пример утечки через статический кэш:

public class LeakyCache {
    private static final Map<String, Object> CACHE = new HashMap<>();

    public static void store(String key, Object value) {
        CACHE.put(key, value); // Объект 'value' теперь достижим через статическое поле
    }
    // Нет метода для удаления -> объекты живут вечно, вызывая утечку.
}

Лучшие практики для управления временем жизни:

  • Для кэшей используйте WeakHashMap или SoftReference, которые позволяют GC собирать объекты при нехватке памяти.
  • Явно обнуляйте ссылки (ref = null), когда объект больше не нужен.
  • Используйте try-with-resources для автоматического закрытия ресурсов (AutoCloseable).