Какая разница между java.lang.ref.WeakReference
а java.lang.ref.SoftReference
?
java
reference
weak-references
soft-references
driekken
источник
источник
Ответы:
От понимания слабых ссылок , Итан Николас:
А Питер Кесслер добавил в комментарии:
источник
Слабые ссылки собраны с нетерпением. Если GC обнаружит, что объект является слабо достижимым (достижимым только по слабым ссылкам), он немедленно очистит слабые ссылки на этот объект. Таким образом, они хороши для хранения ссылки на объект, для которого ваша программа также хранит (строго ссылаются) «связанную информацию», например, кэшированную информацию об отражении класса, или оболочку для объекта и т. Д. Все, что делает нет смысла сохранять после того, как объект, с которым он связан, является GC-ed. Когда слабая ссылка очищается, она помещается в очередь ссылок, которую ваш код где-то опрашивает, а также отбрасывает связанные объекты. То есть вы сохраняете дополнительную информацию об объекте, но эта информация не нужна, когда объект, на который он ссылается, исчезает. Фактически, в некоторых ситуациях вы можете даже создать подкласс WeakReference и сохранить связанную дополнительную информацию об объекте в полях подкласса WeakReference. Другое типичное использование WeakReference в сочетании с Maps для хранения канонических экземпляров.
SoftReferences, с другой стороны, хороши для кэширования внешних восстанавливаемых ресурсов, поскольку GC обычно задерживает их очистку. Однако гарантируется, что все SoftReferences будут очищены до того, как будет выдан OutOfMemoryError, поэтому они теоретически не могут вызвать OOME [*].
Типичным примером использования является сохранение проанализированной формы содержимого из файла. Вы реализуете систему, в которой вы загружаете файл, анализируете его и сохраняете SoftReference для корневого объекта анализируемого представления. В следующий раз, когда вам понадобится файл, вы попытаетесь получить его через SoftReference. Если вы можете получить его, вы избавили себя от другой загрузки / разбора, и если GC тем временем очистил его, вы перезагрузите его. Таким образом, вы используете свободную память для оптимизации производительности, но не рискуете OOME.
Теперь для [*]. Хранение SoftReference не может вызвать OOME само по себе. Если, с другой стороны, вы по ошибке используете SoftReference для задачи, которая предназначена для использования WeakReference (а именно, вы храните информацию, связанную с объектом, как-то строго ссылающейся, и отбрасываете ее, когда очищается объект Reference), вы можете запустить OOME как Ваш код, который опрашивает ReferenceQueue и удаляет связанные объекты, может не запуститься своевременно.
Таким образом, решение зависит от использования - если вы кэшируете информацию, которую дорого построить, но тем не менее восстанавливаемую из других данных, используйте мягкие ссылки - если вы сохраняете ссылку на канонический экземпляр некоторых данных, или вы хотите иметь ссылку на объект, не «владея» им (таким образом предотвращая его GC'd), используйте слабую ссылку.
источник
WeakReference
является то, что в тех местах, где его следует использовать, тот факт, что он может оставаться действительным в течение некоторого времени после того, как ссылка выходит из области видимости, может быть допустимым, но нежелательным.WeakReference
которое заключается в наблюдении за запусками GC. См. Подробности: stackoverflow.com/a/46291143/632951На Java ; Порядок от самого сильного до самого слабого, есть: сильный, мягкий, слабый и призрачный
Сильная ссылка нормальная ссылка , которая защищает упомянутый объект из коллекции с помощью ОГО. т.е. никогда не собирает мусор.
Мягкая ссылка имеет право для сбора сборщика мусора, но , вероятно , не будет собираться , пока его память не требуется. т.е. мусор собирает раньше
OutOfMemoryError
.Слабая ссылка является ссылкой , что не защищает объект , на который ссылается из коллекции с помощью ГХ. т.е. мусор собирается, когда нет сильных или мягких рефсов.
Фантом ссылка является ссылка на объект phantomly ссылается после того, как она была завершена, но до его выделенная память была утилизирована.
Источник
Аналогия. Предположим, JVM - это королевство, Object - король королевства, а GC - атакующий королевства, который пытается убить короля (объект).
источник
until memory is available
не имеет смысла. Вы имеете в видуis eligible for collection by garbage collector, but probably won't be collected until its memory is needed for another use
?Слабая ссылка http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html
Принцип:
weak reference
связан со сборкой мусора. Обычно объект, имеющий один или несколько объектов, неreference
будет иметь права на сборку мусора.Вышеуказанный принцип не применим, когда он есть
weak reference
. Если объект имеет слабую ссылку на другие объекты, он готов к сборке мусора.Давайте посмотрим на приведенный ниже пример: у нас есть объект
Map
with, где Key ссылается на объект.Теперь во время выполнения программы мы сделали
emp = null
.Map
Холдинг ключ не имеет смысла здесь , как этоnull
. В описанной выше ситуации объект не является сборщиком мусора.WeakHashMap
WeakHashMap
это тот, где записи (key-to-value mappings
) будут удалены, когда уже невозможно получить их изMap
.Позвольте мне показать выше пример с WeakHashMap
Вывод: Взял,
20 calls to System.gc()
чтобы привестиaMap size
к: 0.WeakHashMap
имеет только слабые ссылки на ключи, а не сильные ссылки, как другиеMap
классы. Существуют ситуации, о которых вам нужно позаботиться, когда значение или ключ имеют строгую ссылку, хотя вы и использовалиWeakHashMap
. Этого можно избежать, обернув объект в WeakReference .Мягкие ссылки.
Soft Reference
немного сильнее, что слабая ссылка. Мягкая ссылка позволяет собирать мусор, но умоляет сборщик мусора очистить его, только если нет другой опции.Сборщик мусора не собирает агрессивно доступные объекты, как это происходит со слабо достижимыми объектами - вместо этого он собирает объекты, которые легко достижимы, только если ему действительно «нужна» память. Мягкие ссылки - это способ сказать сборщику мусора: «Пока память не слишком тесная, я бы хотел сохранить этот объект. Но если память становится действительно тесной, продолжайте собирать ее, и я разберусь» с этим. " Сборщик мусора требуется очистить все мягкие ссылки, прежде чем он может бросить
OutOfMemoryError
.источник
NullPointerException
по прибытиюaMap.get().put(...)
.WeakHashMap
пример (поскольку это первый пример, демонстрирующий слабое поведение). Посмотрите на документ «WeakHashMap»:"An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. "
весь смысл использования WeakHashMap заключается в том, что вам не нужно объявлять / передавать WeakReference; WeakHashMap делает это для вас, внутренне. docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.htmlWeakHashMap
в действии, с примером приложения, показывающего, как удаляются записи только после выполнения сборки мусора, см. Мой ответ на вопрос: « Всегда ли WeakHashMap постоянно растет, или он очищает ключи мусора? ,Единственная реальная разница между мягкой ссылкой и слабой ссылкой заключается в том, что
источник
SoftReference
предназначен для кешей. Когда будет обнаружено, что онWeakReference
ссылается на недоступный в противном случае объект, он сразу же будет очищен.SoftReference
можно оставить как есть. Как правило, существует некоторый алгоритм, касающийся количества свободной памяти и времени, использованного последним, чтобы определить, следует ли ее очистить. Текущий алгоритм Sun предназначен для очистки ссылки, если она не использовалась в течение стольких секунд, поскольку в куче Java есть свободные мегабайты памяти (настраивается, сервер HotSpot проверяет максимально возможную кучу, как установлено-Xmx
).SoftReference
s будет очищено до того, какOutOfMemoryError
будет брошено, если иное не достижимо.источник
java.lang
. Такое злоупотребление синонимами никому не приносит пользы.Эта статья может быть очень полезна для понимания сильных, мягких, слабых и фантомных ссылок.
Чтобы дать вам резюме,
Если у вас есть только слабые ссылки на объект (без сильных ссылок), то объект будет восстановлен GC в следующем цикле GC.
Если у вас есть только мягкие ссылки на объект (без сильных ссылок), то объект будет возвращен GC только тогда, когда JVM не хватит памяти.
Таким образом, вы можете сказать, что сильные ссылки имеют максимальную силу (никогда не могут быть собраны GC)
Мягкие ссылки более эффективны, чем слабые (поскольку они могут избежать цикла GC до тех пор, пока JVM не исчерпает память)
Слабые ссылки даже менее мощны, чем мягкие ссылки (поскольку они не могут спровоцировать какой-либо цикл GC и будут исправлены, если у объекта нет другой сильной ссылки).
Ресторанная аналогия
Теперь, если вы являетесь сильным клиентом (аналог сильной рекомендации), то даже если в ресторан приходит новый клиент или что-то такое, что всегда радует, вы никогда не покинете свой стол (область памяти в куче). Официант не имеет права говорить вам (или даже просить вас) покинуть ресторан.
Если вы мягкий клиент (аналог мягкого отзыва), то, если в ресторан приходит новый клиент, официант не будет просить вас покинуть стол, если не осталось другой пустой таблицы для размещения нового клиента. (Другими словами, официант попросит вас покинуть стол только в том случае, если заходит новый клиент, и для этого нового клиента не осталось другой таблицы)
Если вы слабый клиент (аналог слабой ссылки), тогда официант по своему желанию может (в любой момент) попросить вас покинуть ресторан: P
источник
Единственная реальная разница
Согласно документу , свободные WeakReferences должны быть очищены работающим GC.
Согласно документу , свободные SoftReferences должны быть очищены, прежде чем OOM выбрасывается.
Это единственная реальная разница. Все остальное не является частью договора. (Я предполагаю, что последние документы являются договорными.)
SoftReferences полезны. Кэши, чувствительные к памяти, используют SoftReferences, а не WeakReferences.
Единственное правильное использование WeakReference - наблюдать за запуском GC. Вы делаете это, создавая новую WeakReference, чей объект немедленно выходит из области видимости, а затем пытаетесь получить значение null
weak_ref.get()
. Когда это происходитnull
, вы узнаете, что между этой продолжительностью GC запускается.Что касается неправильного использования WeakReference, список бесконечен:
бесполезный хак для реализации softreference с приоритетом 2, такой, что вам не нужно писать его, но он не работает должным образом, потому что кеш будет очищаться при каждом запуске GC, даже если есть запасная память. См. Https://stackoverflow.com/a/3243242/632951 для фаз. (Кроме того, что если вам нужно более 2 уровней приоритета кэша? Для этого вам все равно нужна настоящая библиотека.)
паршивый хак, чтобы связать данные с объектом существующего класса, но он создает утечку памяти (OutOfMemoryError), когда ваш GC решает сделать перерыв после создания ваших слабых ссылок. Кроме того, это ужасно: лучший подход - использовать кортежи.
паршивый хак, чтобы связать данные с объектом существующего класса, где у этого класса есть смелость сделать себя не подклассифицированным, и он используется в существующем коде функции, который вам нужно вызвать. В таком случае правильное решение состоит в том, чтобы либо отредактировать класс и сделать его подклассифицированным, либо отредактировать функцию и заставить ее использовать интерфейс вместо класса, либо использовать альтернативную функцию.
источник
equals()
это просто идентификация объекта? Мягкие ссылки там кажутся пустой тратой, потому что, как только ключевой объект перестает быть сильно доступным, никто никогда не будет искать это отображение снова.Шесть типов состояний достижимости объектов в Java:
Для получения более подробной информации: https://www.artima.com/insidejvm/ed2/gc16.html «свернуть
источник
Следует помнить, что объект со слабой ссылкой будет собираться только тогда, когда у него ТОЛЬКО слабые ссылки. Если в нем содержится только одна сильная ссылка, она не собирается независимо от того, сколько у нее слабых ссылок.
источник
Чтобы дать аспект использования памяти в действии, я провел эксперимент с ссылками Strong, Soft, Weak & Phantom при большой нагрузке с тяжелыми объектами, сохранив их до конца программы. Затем следил за использованием кучи и поведением GC . Эти показатели могут варьироваться от случая к случаю, но, безусловно, дают понимание высокого уровня. Ниже приведены выводы.
Поведение кучи и GC под большой нагрузкой
Вы можете получить более подробные графики, статистику, наблюдения для этого эксперимента здесь .
источник
WeakReference : объекты, на которые имеются только слабые ссылки, собираются при каждом цикле GC (незначительном или полном).
SoftReference : когда объекты, на которые имеются только мягкие ссылки, собираются, зависит от:
-XX: SoftRefLRUPolicyMSPerMB = N флаг (значение по умолчанию 1000, то есть 1 секунда)
Количество свободной памяти в куче.
Пример:
Тогда объект, на который ссылается только SoftReference, будет собран, если в последний раз, когда к нему обращались, было больше 10 секунд.
источник