Когда вы будете использовать WeakHashMap или WeakReference?

Использование слабых ссылок - это то, что я никогда не видел в реализации, поэтому я пытаюсь выяснить, что для них используется и как будет реализована реализация. Когда вам нужно использовать WeakHashMap или WeakReference и как он использовался?

Ответ 1

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

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

Понимание слабых ссылок, Этан Николас

Ответ 2

WeakReference и SoftReference

Следует четко различать разницу между WeakReference и SoftReference.

По сути, WeakReference будет GC-d by the JVM с нетерпением, если на указанный объект нет жестких ссылок на него. С другой стороны, объект SoftReference d будет собираться сборщиком мусора до тех пор, пока ему действительно не понадобится освободить память.

Кэш, в котором значения хранятся внутри WeakReference, будет довольно бесполезным (в WeakHashMap это ключи, на которые слабо ссылаются). SoftReferences полезны для переноса значений, когда вы хотите реализовать кеш, который может увеличиваться и уменьшаться с доступной памятью.

Ответ 3

Одно общее использование WeakReference и WeakHashMap в частности - это добавление свойств к объектам. Иногда вы хотите добавить некоторую функциональность или данные к объекту, но подклассы и/или состав не являются опцией, в этом случае очевидной задачей было бы создать хэш-карту, связывающую объект, который вы хотите расширить, к свойству, которое вы хотите добавить, то всякий раз, когда вам нужно свойство, вы можете просто посмотреть его на карте. Однако, если объекты, которые вы добавляете в свойствах, как правило, разрушаются и создаются очень много, вы можете получить много старых объектов на карте, занимающих много памяти.

Если вы используете WeakHashMap, вместо этого объекты оставят вашу карту, как только они больше не будут использоваться остальной частью вашей программы, что является желаемым поведением.

Мне пришлось сделать это, чтобы добавить некоторые данные в java.awt.Component, чтобы обойти изменение JRE между 1.4.2 и 1.5, я мог бы исправить его, выполнив подклассирование каждого компонента, в котором меня интересовал int (JButton, JFrame, JPanel....), но это было намного проще с гораздо меньшим количеством кода.

Ответ 4

Еще один полезный случай для WeakHashMap и WeakReference - это реализация реестре при прослушивании.

Когда вы создаете что-то, что хочет прослушать определенные события, обычно вы регистрируете слушателя, например.

manager.registerListener(myListenerImpl);

Если manager хранит ваш слушатель с помощью WeakReference, это означает, что вам не нужно удалять регистр, например. с manager.removeListener(myListenerImpl), потому что он будет автоматически удален после того, как ваш слушатель или ваш компонент, удерживающий слушателя, станет недоступен.

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

Где WeakHashMap входит в изображение?

Реестру слушателя, которому требуется хранить зарегистрированных слушателей как WeakReference, требуется коллекция для хранения этих ссылок. Реализация WeakHashSet в стандартной библиотеке Java отсутствует только WeakHashMap, но мы можем легко использовать последнюю, чтобы "реализовать" функциональность первого:

Set<ListenerType> listenerSet =
    Collections.newSetFromMap(new WeakHashMap<ListenerType, Boolean>());

С помощью этого listenerSet для регистрации нового прослушивателя вам просто нужно добавить его в набор, и даже если он не будет удален явно, если слушатель больше не ссылается, он автоматически удаляется JVM.

Ответ 5

Это сообщение в блоге демонстрирует использование обоих классов: Java: синхронизация по идентификатору. Использование выглядит примерно так:

private static IdMutexProvider MUTEX_PROVIDER = new IdMutexProvider();

public void performTask(String resourceId) {
    IdMutexProvider.Mutex mutext = MUTEX_PROVIDER.getMutex(resourceId);
    synchronized (mutext) {
        // look up the resource and do something with it
    }
}

IdMutextProvider предоставляет объекты на основе id для синхронизации. Требования:

  • должен возвращать ссылку на тот же объект для одновременного использования эквивалентных идентификаторов
  • должен возвращать другой объект для разных идентификаторов
  • механизм освобождения (объекты не возвращаются поставщику)
  • не должен протекать (неиспользуемые объекты имеют право на сбор мусора)

Это достигается с помощью внутренней карты памяти типа:

WeakHashMap<Mutex, WeakReference<Mutex>>

Объект является как ключом, так и значением. Когда ничего внешнего к карте не имеет жесткой ссылки на объект, это может быть сбор мусора. Значения на карте хранятся с жесткими ссылками, поэтому значение должно быть обернуто в WeakReference, чтобы предотвратить утечку памяти. Этот последний пункт описан в javadoc.

Ответ 6

Если вы, например, хотите отслеживать все объекты, созданные из определенного класса. Чтобы позволить этим объектам собирать мусор, вы сохраняете список/карту слабых ссылок на объекты, а не сами объекты.

Теперь, если кто-то может объяснить мне phantom -references, я был бы счастлив...

Ответ 7

Как указано выше, слабая ссылка сохраняется до тех пор, пока существует сильная ссылка.

Примером использования будет использование WeakReference внутри слушателей, так что слушатели перестанут активны, как только основная ссылка на их целевой объект исчезнет. Обратите внимание, что это не означает, что WeakReference удаляется из списка прослушивателей, очистка по-прежнему требуется, но может выполняться, например, в запланированные сроки. Это также приводит к тому, что объект, прослушиваемый, не может содержать сильные ссылки и в конечном итоге стать источником памяти. Пример: Swing GUI-компоненты, ссылающиеся на модель с более длительным жизненным циклом, чем окно.

Во время игры с прослушивателями, как описано выше, мы быстро поняли, что объекты собираются "сразу" с точки зрения пользователя.

Ответ 8

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

Ответ 9

Я выполнил поиск кода Google для "new WeakHashMap()".

У меня есть куча совпадений из проекта pathpath GNU и

Ответ 10

вы можете использовать weakhashmap для реализации ресурсоемкого кеширования для создания расширенного объекта.

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