WeakHashMap и строго ссылаются - PullRequest
8 голосов
/ 07 февраля 2012

Javadocs говорит: «Когда ключ был удален, его запись эффективно удаляется с карты».

Но если не существует другого потока, который иногда удаляет такие Map.Entry записи, выигралне являются ли объекты значимости сильной ссылкой на карту?Но поскольку такой поток не запущен, только вызовы метода get могут удалять такие записи - по одной за раз.

По этой причине я почти всегда использую WeakHashMap<K, WeakReference<V>>.Почему бы им не сделать это поведение по умолчанию - значения также считаются слабыми ссылками?

1 Ответ

9 голосов
/ 07 февраля 2012

Справочные очереди используются для автоматического удаления записей.

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/ReferenceQueue.html

Очереди ссылок, к которым зарегистрированные сборщики объектов добавляются сборщиком мусора после обнаружения соответствующих изменений достижимости.

По сути, слабые ссылки являются основной частью сборщика мусора, поэтому, когда происходит очистка GC, неиспользуемые ссылки обнаруживаются и помещаются в очереди, а затем могут быть предприняты действия на основе содержимого этих очередей.

Поток может находиться в очереди remove, чтобы получать оповещения о необходимости очистки или poll очереди.

«Теория и практика Java: устранение утечек памяти со слабыми ссылками» объясняет:

Реализация WeakHashMap иллюстрирует общую идиому со слабыми ссылками - что некоторый внутренний объект расширяет WeakReference.

...

WeakHashMap использует слабые ссылки для хранения ключей карты, что позволяет собирать мусор для ключевых объектов, когда они больше не используются приложением, а реализация get() может отличить живое отображение от мертвого по тому, WeakReference.get() возвращает null. Но это только половина того, что необходимо для предотвращения увеличения потребления памяти на карте в течение всего жизненного цикла приложения; необходимо также что-то сделать, чтобы удалить мертвые записи с карты после того, как ключевой объект был собран. В противном случае карта просто будет заполнена записями, соответствующими мертвым ключам. И хотя это будет невидимо для приложения, оно все равно может вызвать нехватку памяти в приложении, поскольку Map.Entry и объекты-значения не будет собрана, даже если ключ.

...

Очереди ссылок являются основным средством сбора мусора для обратной передачи приложению информации о жизненном цикле объекта. Слабые ссылки имеют два конструктора: один принимает в качестве аргумента только референт, а другой - также очередь ссылок. , Когда слабая ссылка была создана со связанной эталонной очередью, и референт становится кандидатом в GC, эталонный объект (не референт) ставится в очередь эталонной очереди после очистки ссылки. Затем приложение может извлечь ссылку из очереди ссылок и узнать, что референт был собран, чтобы оно могло выполнить связанные действия по очистке, такие как удаление записей для объектов, выпавших из слабой коллекции. (Справочные очереди предлагают те же режимы удаления из очереди, что и BlockingQueue - опрашиваемые, синхронизированные по времени и не синхронизированные.)

EDIT:

Даже с очередями слабые карты все еще могут течь. Эфемероны - это попытка разрешить случай, когда слабый ключ ссылается на строгое значение, которое ссылается на ключ. Они не могут быть реализованы в Java.

Эфемероны решают проблему, которая обычно встречается при попытке «прикрепить» свойства к объектам с помощью реестра. Когда какое-либо свойство должно быть присоединено к объекту, свойство должно (с точки зрения поведения GC) обычно иметь время жизни, которое будет иметь переменная экземпляра этого объекта. Однако это осложняется наличием внешней ассоциации между объектом и его свойством, такой как:

property --------- registry --------- association --------- object

Здесь реестр (третье лицо) будет хранить саму ассоциацию, что потребует ручного удаления из реестра (вместо автоматической сборки мусора). Хотя эту проблему всегда можно решить в любой конкретной конкретной ситуации, используя один из различных типов слабых ассоциаций, выбор «правильного» типа ассоциации зависит от множества факторов, некоторые из которых могут динамически меняться.

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

...