Есть ли SoftHashMap в Java?


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

6 56

6 ответов:

Edit (Aug. 2012):

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


Не так Я знаю (ноября. 2008), но вы вроде находите какую-то реализацию SoftHashMap в сети.

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


Edit (Nov. 2009)
Как Маттиас упоминает в комментариях Google GuavaMapMaker использует ли SoftReferences:

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

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

как говорится в этой теме, другой кандидат 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.апаш.палата общин.коллекции.карта.ReferenceMap; он не поддерживает временное удаление, но он поддерживает выбор, следует ли сравнивать ключи по идентичности или по равенству. Кроме того, эта реализация не является параллельной - она может быть синхронизирована, но это работает менее хорошо при доступе из нескольких потоков.

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

  1. Apache Commons: org.апаш.палата общин.коллекции.карта.ReferenceMap

  2. Коллекции Google: com.гуглить.общий.собирать.ReferenceMap

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

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

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

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

Runtime.getRuntime().getFreeMemory();

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

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

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