Что такое Weak Reference (слабая ссылка) в Java?

Ответ

Weak Reference (слабая ссылка) — это один из видов ссылок в Java (java.lang.ref.WeakReference), которая не защищает свой референт (объект) от сборщика мусора (GC). Если на объект остались только слабые ссылки, GC удалит этот объект при следующем запуске, а ссылка автоматически вернет null.

Цель использования: Реализация кэшей в памяти, где данные могут быть безопасно удалены при нехватке памяти, не вызывая OutOfMemoryError. Объект в таком кэше существует, пока на него где-то еще есть "сильная" ссылка.

Пример создания и использования:

import java.lang.ref.WeakReference;

public class WeakReferenceExample {
    public static void main(String[] args) {
        // 1. Создаем объект и слабую ссылку на него
        Object strongRef = new Object(); // "Сильная" ссылка
        WeakReference<Object> weakRef = new WeakReference<>(strongRef);

        System.out.println("До GC: " + weakRef.get()); // Вернет объект

        // 2. Удаляем сильную ссылку. Теперь на объект ссылается только weakRef.
        strongRef = null;

        // 3. Запускаем сборку мусора (запрос, не гарантия)
        System.gc();

        // 4. Даем GC немного времени
        try { Thread.sleep(100); } catch (InterruptedException e) {}

        System.out.println("После GC: " + weakRef.get()); // Вернет null
    }
}

Иерархия ссылок в java.lang.ref (от самой сильной к самой слабой):

  1. Strong Reference — обычная ссылка (Object obj = new Object()). Объект не будет собран, пока существует такая ссылка.
  2. Soft Reference (SoftReference) — удаляется только при острой нехватке памяти. Подходит для кэшей, которые должны очищаться перед OutOfMemoryError.
  3. Weak Reference (WeakReference) — удаляется при следующем запуске GC, как только пропадают сильные ссылки.
  4. Phantom Reference (PhantomReference) — самая слабая. Используется для точного контроля над финализацией (получения уведомления перед удалением).

Типичный use case: Ключи в WeakHashMap являются слабыми ссылками, что позволяет автоматически удалять записи из мапы, когда ключ-объект больше не используется в программе.

Ответ 18+ 🔞

А, ну это про слабые ссылки, блядь! Слабые, сука, как моя сила воли после пятницы! Слушай сюда, сейчас разжую.

Вот представь: есть у тебя объект, как последняя бутылка пива в холодильнике. Пока ты за неё держишься — это сильная ссылка, её ни хуя не отберут. А слабая ссылка — это как твой друг, который говорит: «О, пиво есть!» — но если ты эту бутылку уже выпил и выкинул, то друг твой приходит, смотрит на пустое место и такой: «Ну, похуй».

Вот WeakReference в Java — это ровно эта хуйня. Она не защищает объект от сборщика мусора. Если на объект остались только слабые ссылки — GC прибежит, как голодный алкаш на халяву, и вынесет этот объект в мусорку, а ссылка станет null. И всё, пиздец.

Зачем это надо? Ну, например, для кэшей в памяти, чтобы не вылетать с OutOfMemoryError. Данные висят, пока они кому-то нужны (есть сильные ссылки), а как перестали — их можно смело выносить, память освободится.

Смотри, как это выглядит в коде, ёпта:

import java.lang.ref.WeakReference;

public class WeakReferenceExample {
    public static void main(String[] args) {
        // 1. Создаём объект и слабую ссылку на него
        Object strongRef = new Object(); // Вот это — сильная ссылка, крепкая, как удар с правой
        WeakReference<Object> weakRef = new WeakReference<>(strongRef);

        System.out.println("До GC: " + weakRef.get()); // Вернёт объект, всё ок

        // 2. Убираем сильную ссылку. Теперь на объект смотрит только слабая.
        strongRef = null;

        // 3. Зовём сборщика мусора (не гарантия, но запрос)
        System.gc();

        // 4. Ждём чутка, чтобы GC успел поработать
        try { Thread.sleep(100); } catch (InterruptedException e) {}

        System.out.println("После GC: " + weakRef.get()); // Вернёт null, объект сгинул
    }
}

А ещё есть целая иерархия ссылок, блядь, от самых упоротых до совсем хиленьких:

  1. Strong Reference — обычная ссылка, Object obj = new Object();. Пока она есть — объект живёт, как царь.
  2. Soft Reference (SoftReference) — удаляется только когда память уже совсем припёрло, перед самым OutOfMemoryError. Для кэшей, которые хочется держать подольше.
  3. Weak Reference (WeakReference) — как раз наш случай. Как только сильные ссылки пропали — объект идёт нахуй при первом же GC.
  4. Phantom Reference (PhantomReference) — вообще самая слабая, призрачная, блядь. Нужна, чтобы точно узнать, когда объект уже почти удалён, но ещё не окончательно. Для всякой тонкой работы с финализацией.

Ну и классический пример использования — WeakHashMap. Там ключи хранятся как слабые ссылки. Если ключ-объект больше нигде не используется (нет сильных ссылок) — запись из мапы автоматом выпиливается. Удобно, сука, не нужно вручную чистить. Как будто кто-то за тобой убирает пустые бутылки после вечеринки.