Есть ли SoftHashMap в Java? - PullRequest
       31

Есть ли SoftHashMap в Java?

59 голосов
/ 05 ноября 2008

Я знаю, что есть WeakHashMap в java.util, но поскольку он использует WeakReference s для всего, на что ссылается только этот Map, ссылочные объекты будут потеряны в следующем цикле GC. Так что это почти бесполезно, если вы хотите кэшировать случайные данные, которые, скорее всего, будут запрошены снова, не будучи жестко связанными в остальное время. Лучшим решением будет карта, в которой вместо этого используется SoftReference s, но я не нашел ее в пакете Java RT.

Ответы [ 6 ]

28 голосов
/ 05 ноября 2008

Редактировать (август 2012 г.):

Оказывается, в настоящее время лучшим решением, вероятно, являются Cache классы Guava 13.0, описанные в Wiki Guava - это то, что я собираюсь использовать. Он даже поддерживает создание SoftHashMap (см. CacheBuilder.newBuilder().softKeys()), но, вероятно, это не то, что вам нужно, как объясняет эксперт по Java Джереми Мэнсон (ниже вы найдете ссылку).


Не то, чтобы я знал о (ноябрь 2008 г.), но вы можете найти какую-то реализацию SoftHashMap в сети.

Как этот: SoftHashMap или этот .


Редактировать (ноябрь 2009 г.)
Как Матиас упоминает в комментариях, Google Guava MapMaker действительно использует SoftReferences:

A ConcurrentMap строитель, предоставляющий любую комбинацию этих функций:

  • мягкие или слабые клавиши,
  • мягкие или слабые значения,
  • истечение времени и
  • вычисление значений по требованию.

Как уже упоминалось в этой теме , другой кандидат JSR166y:

jsr166y.ConcurrentReferenceHashMap

Он предоставляет альтернативную параллельную справочную карту для реализации Google (которая использует фоновый поток для удаления записей)


Редактировать (август 2012)

Реализация Google использует фоновый поток только тогда, когда запрошено истечение срока действия записей. В частности, он просто использует java.util.Timer, который не так навязчив, как отдельный фоновый поток.

Джереми Мэнсон рекомендует для любого кэша использовать эту функцию, чтобы избежать опасностей SoftReference: http://jeremymanson.blogspot.de/2009/07/how-hotspot-decides-to-clear_07.html

Существует еще одна реализация из Apache Commons , а именно org.apache.commons.collections.map.ReferenceMap ; он не поддерживает удаление по времени, но он поддерживает выбор того, должны ли ключи сравниваться по идентичности или по равенству. Более того, эта реализация не параллельна - ее можно синхронизировать, но она работает хуже при доступе из нескольких потоков.

20 голосов
/ 30 декабря 2008

Я знаком с двумя библиотеками, которые предлагают реализацию SoftHashMap:

  1. Apache Commons : org.apache.commons.collections.map.ReferenceMap

  2. Коллекции Google : com.google.common.collect.ReferenceMap

3 голосов
/ 05 ноября 2008
2 голосов
/ 05 октября 2011

Apache Shiro поставляется с SoftHashMap, предназначенным для кэширования. Он основан на статье, опубликованной jb выше и лицензированной под Apache v2. Вы можете найти документацию здесь и исходный код здесь .

2 голосов
/ 26 ноября 2009

Рассматривали ли вы использовать LRUMap вместо мягкой HashMap? Вы получаете больше контроля над тем, что хранится (или, по крайней мере, сколько).

1 голос
/ 05 ноября 2008

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

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

Runtime.getRuntime().getFreeMemory();

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

вот кэш LRU i, разработанный с O (1) временем вставки, удаления и поиска, который имеет настраиваемое максимальное количество элементов. Если вам нужен кеш, то это будет лучшим решением, чем SoftHashMap.

Мягкие ссылки - отличный способ создать расширяемый кеш. Таким образом, идеальным решением было бы использовать SoftHashMap вместе с обычным кэшем фиксированного размера. пусть все вставки в кеш идут как в фиксированный кеш, так и в мягкую хеш-карту, а затем для ссылки на что-то, просто посмотрите, есть ли это в мягкой хэш-карте (и обновите эталонное время в кеше). таким образом, все ваши самые важные элементы (в соответствии с выбранной вами политикой LRU, MFU, ...) никогда не будут удалены, поскольку на них жестко ссылаются в кеше, но вы также будете придерживаться большего количества вещей (без контроля политики) до тех пор, пока так как памяти достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...