Как эффективно кэшировать объекты в Java, используя доступную оперативную память? - PullRequest
25 голосов
/ 29 января 2010

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

Мои требования:

  • Простой и легкий
  • Не намного медленнее, чем обычный HashMap
  • Использовать LRU или некоторую политику удаления, которая приближается к LRU

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

Мой текущий подход заключается в использовании MapMaker из Google Collection следующим образом:

Map<String, Object> cache = new MapMaker().softKeys().makeMap();

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

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

Ответы [ 12 ]

0 голосов
/ 29 января 2010

Используя существующий кеш, сохраняйте WeakReference, а не обычные ссылки на объекты.

Если в GC заканчивается свободное место, значения, хранящиеся в WeakReferences, будут освобождены.

0 голосов
/ 29 января 2010

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

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

Большинство решений, которые вы найдете, будут функциями, добавленными поверх классов Java-карт, включая EhCache.

Вы смотрели на коллекций общин LRUMap?

Обратите внимание, что существует открытый выпуск против MapMaker для обеспечения функциональности LRU / MRU. Возможно, вы также можете высказать свое мнение там

...