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

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

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

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

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

Одно из различий, на которые следует обратить внимание, – это разница между WeakReference и SoftReference .

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

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

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

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

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

Другим полезным случаем для WeakHashMap и WeakReference является реализация реестров слушателей .

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

 manager.registerListener(myListenerImpl); 

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

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

Где находится WeakHashMap ?

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

 Set listenerSet = Collections.newSetFromMap(new WeakHashMap()); 

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

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

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

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

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

 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 для синхронизации. Требования:

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

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

 WeakHashMap> 

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

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

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

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

Я выполнил поиск кода Google для «нового WeakHashMap ()».

Я получил кучу матчей из проекта GNU classpath и

  1. Проект Apache xbean: WeakHashMapEditor.java
  2. Проект Apache Lucene: CachingWrapperFilter.java

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

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

Interesting Posts
Давайте будем гением компьютера.