Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
В какой момент чистятся SoftReference
SoftReference — это тип слабой ссылки в Java, которая позволяет объектам быть собранными сборщиком мусора в определённых условиях. Её очистка (обнуление) происходит не в конкретный момент, а в определённом диапазоне условий, связанных с давлением на память.
Когда происходит очистка
SoftReference объекты удаляются сборщиком мусора в следующих случаях:
- При недостатке памяти — это основное условие. Когда JVM почти исчерпала доступную память и возникает OutOfMemoryError, GC первым делом очищает все SoftReference перед выбросом исключения
- После полной сборки мусора (Full GC) — если обычная сборка мусора не освободила достаточно памяти
- По решению GC алгоритма — детали зависят от реализации JVM (например, HotSpot может учитывать последнее обращение к объекту)
Отличие от других типов ссылок
// StrongReference — стандартная ссылка, не удаляется
val strongRef = MyObject()
// SoftReference — удаляется только при нехватке памяти
val softRef = SoftReference(MyObject())
val obj = softRef.get() // null если объект был удалён
// WeakReference — удаляется при следующем GC если нет strong ссылок
val weakRef = WeakReference(MyObject())
// PhantomReference — удаляется всегда, нужна для очистки ресурсов
val phantomRef = PhantomReference(MyObject(), queue)
Практический пример в Android
CacheManager часто использует SoftReference для кэширования изображений:
class ImageCache {
private val cache = mutableMapOf<String, SoftReference<Bitmap>>()
fun put(key: String, bitmap: Bitmap) {
cache[key] = SoftReference(bitmap)
}
fun get(key: String): Bitmap? {
val ref = cache[key]
val bitmap = ref?.get()
// Если SoftReference вернула null, объект был удалён
if (bitmap == null) {
cache.remove(key)
}
return bitmap
}
}
Важные моменты
- SoftReference.get() может вернуть null в любой момент после вызова GC
- Не гарантируется время удержания объекта в памяти — это зависит от JVM реализации
- Не следует полагаться на SoftReference для освобождения критических ресурсов (используй try-with-resources или PhantomReference)
- На практике SoftReference часто медленнее, чем явное управление кэшем с размером
Поведение по версиям JVM
В HotSpot JVM действует примерно такое правило:
- Время жизни SoftReference ≈ msPerMB × свободная память в МБ
- Например, если -XX:SoftRefLRUPolicyMSPerMB=1000 и свободно 100МБ, то объект может жить ~100 секунд
Когда использовать
SoftReference имеет смысл для:
- Кэширования бинарных данных (изображения, видео)
- Кэширования результатов вычислений
- Когда есть возможность пересчитать/перезагрузить данные
Не используй SoftReference для:
- Хранения состояния UI
- Объектов с критическими ресурсами
- Когда нужна гарантия наличия объекта