Вопрос

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

Это было полезно?

Решение

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

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


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

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


Редактировать (ноябрь.2009)
Как Matthias упоминает в комментариях, что Гуава в Google Картограф использует ли 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, а именно org.apache.commons.collections.map.Справочная карта;он не поддерживает временное удаление, но он поддерживает выбор, следует ли сравнивать ключи по идентификатору или по равенству.Более того, эта реализация не является параллельной - ее можно синхронизировать, но это работает менее хорошо при доступе из нескольких потоков.

Другие советы

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

<Ол>
  • Apache Commons : org.apache.commons.collections.map.ReferenceMap

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

  • Пример реализации приведен в 98 выпуске бюллетеня для специалистов по Java

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

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

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

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

    Runtime.getRuntime().getFreeMemory();
    

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

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

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top