Это старая версия документа!
Слабая ссылка на объект WeakReference
Основной концепт
Простенкий пример кода который показывает как заставить GC работать со слабыми ссылками. В отличии от Optional - WeakReference не даёт не каких гарантий что объект ещё живой.
Сам-же Optional содержит в себе сильную ссылку на объект и объект будет живой для GC пока живой Optional.
MyObj obj = new MyObj(); WeakReference<MyObj> ref = new WeakReference<>(obj); obj = null; // нет сильных ссылок MyObj local = ref.get(); // теперь есть сильная ссылка снова! local.doSomething(); // можно использовать System.gc(); // GC НЕ тронет объект local = null; // убрали последнюю сильную ссылку System.gc(); // теперь объект можно удалить
Таймер привязанный к объекту
Простенький пример: таймер который живой пока живой объект.
Если объект стал недостижим (GC готов удалить), таймер прекращается.
import java.lang.ref.WeakReference; import java.util.concurrent.*; public class AliveTimer { private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); public void start(Object target) { WeakReference<Object> ref = new WeakReference<>(target); scheduler.scheduleAtFixedRate(() -> { if (ref.get() == null) { System.out.println("Object is gone. Stopping timer..."); scheduler.shutdown(); } else { System.out.println("Object still alive"); } }, 0, 1, TimeUnit.SECONDS); } } AliveTimer timer = new AliveTimer(); Object obj = new Object(); timer.start(obj); // через некоторое время: obj = null; System.gc();
Список возможно живых объектов
public interface Listener { void onEvent(); } public class EventSource { private final List<WeakReference<Listener>> listeners = new ArrayList<>(); public void addListener(Listener l) { listeners.add(new WeakReference<>(l)); } public void fire() { for (Iterator<WeakReference<Listener>> it = listeners.iterator(); it.hasNext();) { Listener l = it.next().get(); if (l == null) { it.remove(); // слушатель умер — чистим } else { l.onEvent(); } } } }