Короткий ответ
Разница между ссылками — в моменте, когда GC может удалить объект. SoftReference удерживает объект, пока JVM не столкнётся с нехваткой памяти: сборщик удаляет soft-доступные объекты обычно перед OutOfMemoryError. WeakReference ещё слабее: объект, доступный только по слабой ссылке, может быть удалён уже при ближайшей сборке, как только исчезнут сильные ссылки на него.
Как это работает подробнее
Мягкие ссылки удобны для кэшей, где данные можно пересоздать: они живут максимально долго, но не приводят к переполнению памяти. Слабые ссылки подходят для вспомогательных данных, потерю которых можно пережить; классический пример — WeakHashMap, где записи исчезают, когда их ключи больше не используются сильными ссылками.
PhantomReference — крайний случай: объект, доступный только по фантомной ссылке, фактически уже недоступен, метод get() всегда возвращает null. Фантомные ссылки применяются с ReferenceQueue, чтобы выполнить действия «перед удалением» объекта или надёжно отследить, что объект действительно собран, например для очистки нативных ресурсов.
- Сила удержания убывает: сильные → soft → weak → phantom; при нехватке памяти первыми «падут» phantom, затем weak, затем soft.
- Все три класса из java.lang.ref могут помещать ссылку в ReferenceQueue после обработки объекта сборщиком, что позволяет выполнить пост-обработку.
Что использовать на практике
- Используйте SoftReference для кэшей с пересоздаваемыми данными, когда нужно удержать объект как можно дольше без риска OutOfMemoryError.
- Используйте WeakReference и WeakHashMap для вспомогательных данных, привязанных к жизненному циклу ключа.
- Используйте PhantomReference с ReferenceQueue для гарантированной пост-обработки, например освобождения нативных ресурсов.