← Назад к вопросам

Для чего используют Weak Reference?

2.0 Middle🔥 111 комментариев
#JVM и управление памятью

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Weak Reference в Java

Weak Reference (слабая ссылка) — это тип ссылки на объект, которая не препятствует сборке мусора (garbage collection). Это инструмент для управления памятью, который полезен в специфических сценариях кэширования и метаинформации.

Основная проблема, которую решают Weak References

Обычная (strong) ссылка предотвращает сборку мусора объекта. Если вы кэшируете объекты и на них есть strong ссылки, они никогда не будут удалены, что приводит к утечкам памяти:

// Плохой подход — memory leak
public class ObjectCache {
  private Map<String, SomeObject> cache = new HashMap<>();
  
  public void add(String key, SomeObject obj) {
    cache.put(key, obj); // Strong reference — объект никогда не будет удалён
  }
  
  public SomeObject get(String key) {
    return cache.get(key);
  }
}

Решение: WeakHashMap и WeakReference

Weak Reference позволяет объекту быть собран сборщиком мусора, даже если на него есть ссылка в кэше:

import java.lang.ref.WeakReference;
import java.util.WeakHashMap;

// Вариант 1: WeakHashMap
public class SmartCache<K, V> {
  private WeakHashMap<K, V> cache = new WeakHashMap<>();
  
  public void put(K key, V value) {
    cache.put(key, value);
  }
  
  public V get(K key) {
    return cache.get(key);
  }
}

// Вариант 2: явное использование WeakReference
public class ExplicitWeakRefCache<K, V> {
  private Map<K, WeakReference<V>> cache = new HashMap<>();
  
  public void put(K key, V value) {
    cache.put(key, new WeakReference<>(value));
  }
  
  public V get(K key) {
    WeakReference<V> ref = cache.get(key);
    if (ref == null) return null;
    V value = ref.get();
    if (value == null) {
      cache.remove(key);
    }
    return value;
  }
}

Когда использовать Weak References

1. Кэширование метаинформации о классах

// Spring Framework использует WeakHashMap для кэша методов
private static final WeakHashMap<Class<?>, Method[]> methodCache = 
  new WeakHashMap<>();

2. Listener'ы и Observer'ы

public class EventBus {
  private List<WeakReference<EventListener>> listeners = new ArrayList<>();
  
  public void subscribe(EventListener listener) {
    listeners.add(new WeakReference<>(listener));
  }
  
  public void publish(Event event) {
    listeners.removeIf(ref -> ref.get() == null);
    for (WeakReference<EventListener> ref : listeners) {
      EventListener listener = ref.get();
      if (listener != null) {
        listener.onEvent(event);
      }
    }
  }
}

3. Кэширование объектов с долгим жизненным циклом

public class DataObjectCache {
  private WeakHashMap<String, DataObject> cache = new WeakHashMap<>();
  
  public DataObject loadOrCache(String id) {
    return cache.computeIfAbsent(id, k -> {
      return loadFromDatabase(k);
    });
  }
}

Иерархия ссылок в Java

  • Strong Reference: обычная ссылка, препятствует GC
  • Soft Reference: позволяет GC удалить объект при нехватке памяти
  • Weak Reference: позволяет GC удалить объект в любой момент
  • Phantom Reference: используется только для очистки ресурсов
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

// SoftReference для кэша
SoftReference<LargeObject> softRef = new SoftReference<>(new LargeObject());

// PhantomReference для отслеживания финализации
ReferenceQueue<MyObject> queue = new ReferenceQueue<>();
PhantomReference<MyObject> phantomRef = new PhantomReference<>(new MyObject(), queue);

Плюсы и минусы

Плюсы:

  • Предотвращают memory leaks в кэшах
  • Автоматическая очистка при нехватке памяти
  • Полезны для metadata и listeners

Минусы:

  • Сложнее для понимания
  • Может привести к неожиданным null значениям
  • Требует явной проверки null при получении значения

Weak References — это продвинутый инструмент для тонкого управления памятью в высоконагруженных приложениях и фреймворках.