Страницы

Поиск по вопросам

суббота, 23 марта 2019 г.

Java.Польза от ссылок(SoftReference, WeakReference , PhantomReference)

Используя различные ссылки можно получить большую скорость работы сборщика мусора или для иных целей используются ссылки?


Ответ

Разница не в скорости, разница в том, как сборщик мусора будет работать с объектом по ссылке.
SoftReference — это самая сильная из всех перечисленных ссылок. Если на объект не осталось больше нормальных ссылок, а только SoftReference, объект не будет съеден сборщиком мусора до тех пор, пока реально не возникнет ситуация нехватки памяти.
Хороший пример использования для таких ссылок -- кеш больших картинок в памяти. Если память исчерпалась, картинку выбросит сборщик мусора, и вы сможете перечитать её с диска, когда она снова вам понадобится.
WeakReference слабее: она не увеличивает дополнительно время жизни объекта, на который ссылается, и если на объект есть не более чем слабые ссылки, сборщик мусора может убрать его когда ему вздумается.
Хороший пример использования для таких ссылок -- добавить дополнительную информацию об каком-то объекте. Для этого вы держите в своём контейнере не сам объект, а лишь WeakReference на него, вместе с необходимой информацией, тем самым вы не мешаете объекту умереть вовремя и не меняете свойства остальной части программы.
Имея на руках SoftReference или WeakReference на ещё живой объект, вы можете получить настоящую ("сильную") ссылку, и предотвратить съедение этого объекта сборщиком мусора. Имея сильную ссылку, вы можете работать с объектом как обычно.
PhantomReference ещё слабее. Она не только не предохраняет объект от уборки, она даже не даёт возможности получить сильную ссылку. Вы можете только узнать, что объект собирается умереть, и предпринять какие-то действия по очистке; предотвратить смерть объекта вы не сможете.

При создании SoftReference, WeakReference вы можете, а при создании PhantomReference должны указать ReferenceQueue (хотя тут можно указать null, это обычно бессмысленно). После того, как объект будет убран сборщиком мусора, ссылка попадает в указанную вами ReferenceQueue
Для нефантомных ссылок при добавлении в очередь финализатор уже выполнен и память объекта уже освобождена, но для фантомных добавление происходит после вызова финализатора до очистки памяти. Вы можете по сути не объявлять дорогой финализатор, а воспользоваться фантомной ссылкой из очереди для того, чтобы самостоятельно освободить ассоциированные ресурсы. (Для этого вы не сможете использовать сам объект, т. к. сильную ссылку на него невозможно получить из фантомной ссылки; но вы можете унаследоваться от PhantomReference, чтобы добавить нужную информацию в объект-ссылку.)
Ещё одно отличие, как подсказывает @gstackoverflow в комментариях, состоит в том, что фантомную ссылку вы должны очистить вручную, иначе объект будет оставаться (фантомно) достижим. Только после этого объект будет окончательно удалён.
Источники:
https://stackoverflow.com/q/3329691/276994 https://habrahabr.ru/post/169883/ http://www.javaportal.ru/java/articles/referenceclasses.html

Комментариев нет:

Отправить комментарий