Кто-то может объяснить различие между этими тремя Классами ссылки (или отправить ссылку на хорошее объяснение)? SoftReference
> WeakReference
> PhantomReference
, но когда я использовал бы каждого? Почему там a WeakHashMap
но нет SoftHashMap
или PhantomHashMap
?
И если я использую следующий код...
WeakReference<String> ref = new WeakReference<String>("Hello!");
if (ref != null) { // ref can get collected at any time...
System.gc(); // Let's assume ref gets collected here.
System.out.println(ref.get()); // Now what?!
}
... что происходит? Сделайте я должен проверить если ref
является пустым перед каждым оператором (это неправильно, но что я должен сделать)? Извините за скоропалительные вопросы, но я испытываю затруднения при понимании их Reference
классы... Спасибо!
Ссылка: https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
PhantomHashMap
будет работать не очень хорошо, так как get
всегда возвращает null
для фантомных ссылок.
Кэши сложны, поэтому SoftHashMap
может работать не так хорошо, как вы думаете. Однако я полагаю, что библиотека коллекций Google содержит общую реализацию карты ссылок.
Вы всегда должны проверять, что get
возвращает не null
. (Обратите внимание, что не проверяется, что сама ссылка Reference
не является не-null
). В случае интернированных строк это всегда так, но (как всегда) не пытайтесь быть "умными" в этом вопросе.
Документация по библиотеке Java для пакета java.lang.ref
характеризует уменьшение силы трех явных ссылочных типов.
Вы используете SoftReference
, когда хотите, чтобы объект, на который ссылаются, оставался живым, пока у главного процесса не закончится память. Объект не будет доступен для сбора, пока сборщику не потребуется освободить память. В общем случае привязка SoftReference
означает: "Держите объект, пока не сможете больше".
Напротив, используйте WeakReference
, когда вы не хотите влиять на время жизни объекта; вы просто хотите сделать отдельное утверждение о объекте, на который ссылаетесь, пока он остается живым. Наличие связанных WeakReference
ов не влияет на пригодность объекта для сбора. Что-то вроде внешнего отображения от экземпляра объекта к связанному свойству, где свойство нужно регистрировать только до тех пор, пока жив связанный объект, является хорошим применением для WeakReference
s и WeakHashMap
.
Последний - PhantomReference
- труднее охарактеризовать. Как и WeakReference
, такая связь PhantomReference
не влияет на время жизни ссылающегося объекта. Но в отличие от других ссылочных типов, PhantomReference
нельзя даже разыменовать. В некотором смысле, она не указывает на объект, на который указывает, насколько могут судить вызывающие. Она просто позволяет ассоциировать некоторые связанные данные с объектом, на который ссылается, - данные, которые позже могут быть проверены и обработаны, когда PhantomReference
будет поставлен в очередь в связанной с ним ReferenceQueue
. Обычно тип создается из PhantomReference
и включает некоторые дополнительные данные в этот производный тип. К сожалению, чтобы использовать такой производный тип, необходимо выполнить некоторый даункастинг.
В вашем примере кода не ссылка ref
(или, если хотите, "переменная") может быть нулевой. Скорее, нулевым может быть значение, полученное при вызове Reference#get()
. Если окажется, что оно равно null, то вы опоздали; объект, на который ссылается ссылка, уже на пути к тому, чтобы быть собранным:
final String val = ref.get();
if (null != val)
{
// "val" is now pinned strongly.
}
else
{
// "val" is already ready to be collected.
}