Понимание Классов ссылки Java: SoftReference, WeakReference и PhantomReference

Кто-то может объяснить различие между этими тремя Классами ссылки (или отправить ссылку на хорошее объяснение)? 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 классы... Спасибо!

80
задан Haywood Jablomey 25 July 2010 в 15:18
поделиться

2 ответа

Ссылка: https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references

PhantomHashMap будет работать не очень хорошо, так как get всегда возвращает null для фантомных ссылок.

Кэши сложны, поэтому SoftHashMap может работать не так хорошо, как вы думаете. Однако я полагаю, что библиотека коллекций Google содержит общую реализацию карты ссылок.

Вы всегда должны проверять, что get возвращает не null. (Обратите внимание, что не проверяется, что сама ссылка Reference не является не-null). В случае интернированных строк это всегда так, но (как всегда) не пытайтесь быть "умными" в этом вопросе.

6
ответ дан 24 November 2019 в 10:01
поделиться

Документация по библиотеке Java для пакета java.lang.ref характеризует уменьшение силы трех явных ссылочных типов.

Вы используете SoftReference, когда хотите, чтобы объект, на который ссылаются, оставался живым, пока у главного процесса не закончится память. Объект не будет доступен для сбора, пока сборщику не потребуется освободить память. В общем случае привязка SoftReference означает: "Держите объект, пока не сможете больше".

Напротив, используйте WeakReference, когда вы не хотите влиять на время жизни объекта; вы просто хотите сделать отдельное утверждение о объекте, на который ссылаетесь, пока он остается живым. Наличие связанных WeakReferenceов не влияет на пригодность объекта для сбора. Что-то вроде внешнего отображения от экземпляра объекта к связанному свойству, где свойство нужно регистрировать только до тех пор, пока жив связанный объект, является хорошим применением для WeakReferences и 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.
}
59
ответ дан 24 November 2019 в 10:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: