LRU LinkedHashMap, который ограничивает размер в зависимости от доступной памяти - PullRequest
5 голосов
/ 29 октября 2009

Я хочу создать LinkedHashMap, который будет ограничивать свой размер в зависимости от доступной памяти (т. Е. Когда freeMemory + (maxMemory - allocatedMemory) становится ниже определенного порога). Это будет использоваться в качестве формы кеширования, возможно, с использованием «наименее недавно использованного» в качестве стратегии кеширования.

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

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

Кто-нибудь имеет опыт работы с подобными вещами? Оправдано ли мое беспокойство? Если да, может кто-нибудь предложить хороший подход?

Я должен добавить, что я также хочу иметь возможность "заблокировать" кеш, в основном говоря: "Хорошо, теперь не удаляйте ничего из-за проблем с использованием памяти".

Ответы [ 5 ]

1 голос
/ 04 ноября 2009

Я знаю, что я предвзят, но я действительно должен настоятельно рекомендовать наш MapMaker для этого. Используйте функцию softKeys () или softValues ​​(), в зависимости от того, является ли GC набором ключа или значением, которое более точно описывает, когда запись может быть очищена.

0 голосов
/ 14 марта 2010

У меня была такая же потребность в прошлом, и вот как я реализовал свой кеш:

  • есть менеджер кеш-памяти, который имеет минимальный и максимальный лимит памяти (макс. Лимит в любом случае имеет значение)
  • каждый зарегистрированный кеш имеет следующие (важные) параметры: максимальная емкость (большую часть времени у вас более высокий лимит, вы не хотите занимать больше, чем X элементов) и процент использования памяти
  • Я использую LinkedHashMap и ReentrantReadWriteLock для защиты кэша.
  • при каждом значении X я вычисляю среднее потребление памяти на запись и инициирую вытеснение (асинхронный), если вычисленный предел памяти> допустимый предел памяти.
  • Конечно, вычисление памяти фактически не показывает реальное потребление памяти, но сравнивая вычисленную память с реальным значением (используя профилировщик), я обнаружил, что оно достаточно близко.

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

0 голосов
/ 29 октября 2009

Я бы настоятельно рекомендовал использовать что-то вроде Ehcache вместо переизобретения системы кеширования. Он очень прост в использовании, легко настраивается и прекрасно работает.

0 голосов
/ 30 октября 2009

Как сказал Мэтт Б, что-то вроде Ehcache или JbossCache - хороший первый шаг.

Если вы хотите что-то более легкое и незавершенное, посмотрите коллекции Google. Например, вы можете использовать MapMaker (http://google -collections.googlecode.com / svn / trunk / javadoc / index.html? Com ​​/ google / common / collect / BiMap.html ), чтобы создать карту с мягкими / слабыми ключами и значениями, поэтому он будет кэшировать только те элементы, для которых у него есть место (хотя вы не получите LRU).

0 голосов
/ 29 октября 2009

Кеши, как правило, проблематичны. IIRC, в JRE Sun есть SoftCache, у которого было много проблем.

В любом случае, проще всего использовать SoftReference s на карте. Это должно работать нормально, если накладные расходы SoftReference плюс Map.Entry значительно ниже, чем кэшированные данные.

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

«Блокируя» карту, вы, вероятно, захотите избежать при необходимости. Вам нужно сохранить сильные ссылки на все данные (и исключить, если не ноль). Это будет ужасно.

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