В чем разница между SoftReference и WeakReference в Java?

В современных браузерах вы можете использовать структуру данных Map вместо объекта.

Разработчик mozilla> Map

Объект Map может выполнять итерацию своих элементов в порядке размещения ...

blockquote>

764
задан ArtB 28 March 2019 в 13:58
поделиться

4 ответа

От Слабые ссылки Понимания , Ethan Nicholas:

Слабые ссылки

А слабая ссылка , проще говоря, ссылка, которая не достаточно сильна для принуждения объекта остаться в памяти. Слабые ссылки позволяют Вам усиливать способность сборщика "мусора" определить достижимость для Вас, таким образом, Вы не должны делать этого сами. Вы создаете слабую ссылку как это:

WeakReference weakWidget = new WeakReference(widget);

и затем в другом месте в коде можно использовать weakWidget.get() для получения фактического Widget объект. Конечно, слабая ссылка не достаточно сильна для предотвращения сборки "мусора", таким образом, можно найти (при отсутствии сильных ссылок к виджету), что weakWidget.get() внезапно начинает возвращаться null.

...

Мягкие ссылки

А мягкая ссылка точно похожа на слабую ссылку, за исключением того, что это менее стремится выбросить объект, к которому это относится. Объект, который только слабо достижим (самые сильные ссылки на него WeakReferences) будет отброшен в следующем цикле сборки "мусора", но объект, который мягко достижим, будет обычно слоняться поблизости некоторое время.

SoftReferences не , потребовал вести себя любой по-другому, чем WeakReferences, но на практике мягко достижимые объекты обычно сохраняются, пока память находится в многочисленном предоставлении. Это делает их превосходной основой для кэша, такого как кэш изображений описанный выше, так как можно позволить сборщику "мусора" волноваться об обоих, насколько достижимый объекты (решительно достижимый объект будет никогда быть удаленным из кэша), и как плохо этому нужна память, которую они используют.

И Peter Kessler добавил в комментарии:

JRE Sun действительно рассматривает SoftReferences по-другому по сравнению с WeakReferences. Мы пытаемся держаться для возражения ссылаемый SoftReference, если нет давления на доступную память. Одна деталь: политика для "-клиент" и "-сервер" JRE's отличается: - клиент JRE пытается сохранить Ваше место маленьким, предпочитая очищать SoftReferences, а не разворачивать "кучу", тогда как - сервер JRE пытается поддержать Вашу производительность на высоком уровне, предпочитая разворачивать "кучу" (если возможный), а не очистите SoftReferences. Один размер не соответствует всем.

882
ответ дан itsmysterybox 28 March 2019 в 13:58
поделиться

SoftReference разработан для кэшей. Когда будет найдено, что WeakReference ссылки в других отношениях недостижимый объект, тогда это будет сразу очищено. SoftReference может быть оставлен, как. Обычно существует некоторый алгоритм, имеющий отношение на сумму свободной памяти, и время в последний раз раньше определяло, должно ли это быть очищено. Текущий алгоритм Sun должен очистить ссылку, если это не использовалось за столько же секунд, сколько существуют мегабайты памяти, свободной на "куче" Java (настраивающиеся, сервер проверки HotSpot по сравнению с максимальной возможной "кучей", как установлено -Xmx). SoftReference с будет очищена, прежде OutOfMemoryError брошен, если не в других отношениях достижимый.

22
ответ дан Tom Hawtin - tackline 28 March 2019 в 13:58
поделиться

Слабые ссылки собраны нетерпеливо. Если GC найдет, что объект слабо достижим (достижимый только через слабые ссылки), это очистит слабые ссылки на тот объект сразу. По сути, они хороши для хранения ссылки на объект, для которого Ваша программа также сохраняет (сильно ссылаемой) "связанной информацией" somewere, как кэшируемая отражательная информация о классе или обертка для объекта, и т.д. Что-либо, что не имеет никакого смысла сохранять после объекта, с которым это связано, является редактором GC, Когда слабая ссылка очищена, это ставится в очередь в ссылочной очереди, которую Ваш код опрашивает где-нибудь, и это отбрасывает связанные объекты также. Таким образом, Вы храните дополнительную информацию об объекте, но та информация не нужна однажды объект, к которому это относится, уходит. На самом деле в определенных ситуациях можно даже разделить WeakReference на подклассы и хранить связанную дополнительную информацию об объекте в областях подкласса WeakReference. Другое типичное использование WeakReference в сочетании с Картами для хранения канонических экземпляров.

SoftReferences, с другой стороны, хороши для кэширования внешних, recreatable ресурсов, поскольку GC обычно задерживает очистку их. Это гарантируется, хотя тот весь SoftReferences будет очищен, прежде чем OutOfMemoryError брошен, таким образом, они теоретически не могут вызвать OOME [*].

Типичный пример варианта использования сохраняет проанализированную форму содержание из файла. Вы реализовали бы систему, где Вы загрузите файл, проанализируете его и сохраните SoftReference к корневому объекту проанализированного представления. В следующий раз, когда Вам нужен файл, Вы попытаетесь получить его через SoftReference. Если можно получить его, Вы сэкономили себя другая загрузка/синтаксический анализ, и если GC очистил его тем временем, Вы перезагружаете его. Тем путем Вы используете свободную память для оптимизации производительности, но не рискуете OOME.

Теперь для [*]. Хранение SoftReference не может вызвать OOME сам по себе. С другой стороны, при ошибочном использовании SoftReference для задачи, WeakReference предназначен, чтобы использоваться (а именно, Вы сохраняете информацию связанной с Объектом так или иначе сильно ссылаемый и отбрасываете ее, когда Ссылочный объект очищен), можно столкнуться с OOME как с кодом, который опрашивает ReferenceQueue и отбрасывает связанные объекты, могло бы оказаться, не работал бы своевременно.

Так, решение зависит от использования - при кэшировании информации, которая является дорогой, чтобы создать, но тем не менее reconstructible от других данных, использовать мягкие ссылки - если Вы сохраняете ссылку на канонический экземпляр некоторых данных, или Вы хотите иметь ссылку на объект, не "владея" им (таким образом препятствование тому, чтобы он был GC'd), использовал слабую ссылку.

198
ответ дан driekken 28 March 2019 в 13:58
поделиться

Для предоставления аспекта использования памяти бездействия я сделал эксперимент с Сильным, Мягким, Слабым & Фантомные ссылки под большой нагрузкой с тяжелыми объектами путем сохранения их до конца программы. Затем контролируемое использование "кучи" & поведение GC . Эти метрики могут варьироваться индивидуальное основание, но конечно дают понимание высокого уровня. Ниже результаты.

"куча" & Поведение GC под большой нагрузкой

  • Сильная/Твердая Ссылка - Как продолженная программа, JVM не могла собрать сохраненный сильный ссылочный объект. В конечном счете закончился в "java.lang. OutOfMemoryError: пространство "кучи" Java"
  • Мягкая Ссылка - Как продолженная программа, использование "кучи" продолжало расти, но СТАРЫЙ генерал, GC произошел курица, это приближалось к макс. "куче". GC запустил бит позже вовремя после запуска программы.
  • Слабая ссылка - Как запущенная программа, объекты начали завершать & быть собранным почти сразу. Главным образом объекты были собраны в молодой сборке "мусора" поколения.
  • Фантомная Ссылка - Подобный слабой ссылке, фантомные ссылочные объекты также начали завершаться & собравший "мусор" сразу. Не было никакого старого поколения GC & все объекты становились собранными в самой молодой сборке "мусора" поколения.

можно добраться больше подробно графики, статистика, наблюдения для этого эксперимента здесь .

0
ответ дан 22 November 2019 в 21:22
поделиться
Другие вопросы по тегам:

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