77

Может ли кто-нибудь объяснить разницу между тремя классами Reference (или отправить ссылку на хорошее объяснение)? SoftReference>WeakReference>PhantomReference, но когда я буду использовать каждый? Почему существует WeakHashMap, но нет SoftHashMap или PhantomHashMap?Понимание справочных классов Java: SoftReference, WeakReference и PhantomReference

И если я использую следующий код ...

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

+0

Почему существует «WeakHashMap», но нет «SoftHashMap» или «PhantomHashMap» Отличный вопрос, почему я этого раньше не заметил ...? –

ответ

6

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

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

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

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

+0

Срок действия истек. –

+0

@MehrajMalik Ссылка исправлена. –

57

Библиотека Java documentation for the java.lang.ref package характеризует уменьшающуюся прочность трех явных ссылочных типов.

Вы используете SoftReference, когда хотите, чтобы объект, на который ссылается, оставался в живых, пока хост-процесс не работает в памяти. Объект не будет иметь права на сбор до тех пор, пока коллекционер не нуждается в, чтобы освободить память. Неясно заявлено, что привязка SoftReference означает: «Зацепите объект, пока не сможете больше».

В отличие от этого, используйте WeakReference, если вы не хотите влиять на время жизни объекта ссылки; вы просто хотите сделать отдельное утверждение о ссылочном объекте, пока он остается в живых. На право объекта на сбор не влияют наличие связанных WeakReference s. Что-то вроде внешнего сопоставления из экземпляра объекта в связанное свойство, где свойство нужно записывать только в том случае, если родственный объект жив, полезно использовать для WeakReference s и WeakHashMap.

Последний один - PhantomReference - сложнее охарактеризовать. Подобно WeakReference, такая привязка PhantomReference не влияет на время жизни объекта ссылки. Но, в отличие от других ссылочных типов, нельзя даже разыменовать PhantomReference. В некотором смысле, он не указывает на то, на что он указывает, насколько могут сказать абоненты. Он просто позволяет связать некоторые связанные данные с указанными объектами - данными, которые впоследствии могут быть проверены и обработаны, когда PhantomReference ставится в очередь в связанных с ним ReferenceQueue. Обычно выводится тип от PhantomReference и включает некоторые дополнительные данные в этот производный тип. К сожалению, для использования такого производного типа существует некоторое понижение.

В вашем примере кода это не ссылка ref (или, если хотите, «переменная»), которая может быть нулевой. Скорее, это значение, полученное путем вызова Reference#get(), который может быть нулевым. Если он окажется равным нулю, вы опоздаете; ссылочный объект уже находится на пути к тому, Собрано:

final String val = ref.get(); 
if (null != val) 
{ 
    // "val" is now pinned strongly. 
} 
else 
{ 
    // "val" is already ready to be collected. 
} 
0
String str = new String("hello, world"); 
    WeakReference<String> ref = new WeakReference<String>(str); 
    str = null; 
    if (ref != null) {     
     System.gc(); 
     System.out.println(ref.get()); 
    } 

В этом случае он выдаст значение null. Здесь важна System.gc().

Смежные вопросы