Любые кеши Java, которые могут ограничить использование памяти в кеше в памяти, а не только количество экземпляров? - PullRequest
12 голосов
/ 27 марта 2009

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

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

Итак: существует ли простой Java-кэш с открытым исходным кодом, который позволяет определять «вес» кэшируемых объектов, чтобы ограничить количество кэшируемых объектов?

РЕДАКТИРОВАТЬ (ноябрь 2010 г.): для чего стоит новый проект под названием Java CacheMate , который пытается решить эту проблему, наряду с некоторыми другими идеями по улучшению (многоуровневое хранение в памяти процесс кеширования)

Ответы [ 8 ]

3 голосов
/ 28 марта 2009

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

Размер памяти может быть определен путем включения агента Java, и использование довольно просто при использовании утилиты SizeOf (http://sourceforge.net/projects/sizeof). Я использовал это только в целях отладки, и я бы рекомендовал сравнить накладные расходы прежде чем принять его для нормального использования.

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

Если вам это действительно нужно, и я бы посоветовал этого не делать, мы могли бы улучшить мою текущую реализацию для поддержки этого. Вы можете написать мне, ben.manes-at-gmail.com.

2 голосов
/ 13 ноября 2011

EhCache V2.5 в настоящее время предлагает решение, которое может ограничиваться объемом памяти кеша. Для более подробной информации о покупке Документация EhCache 2.5

2 голосов
/ 30 марта 2009

Как насчет использования простого LinkedHashMap с включенным алгоритмом LRU и размещения всех данных с SoftReference в нем ... таких как cache.out (ключ, новый SoftReference (значение)) ??

Это ограничит ваш кеш объемом доступной памяти, но не уничтожит остальную часть вашей программы, потому что Java удаляет мягкие ссылки, когда есть потребность в памяти ... не все ... сначала самая старая ... обычно. Если вы добавите справочную очередь в свою реализацию, вы также можете удалить записи срывов (только ключ, без значения) с карты.

Это освободило бы вас от расчета размера записей и отслеживания суммы.

0 голосов
/ 30 марта 2009

Можно определить значимую меру для использования памяти кешем. Вы можете вычислить: «оставшийся размер» . К сожалению, вычисление оставшегося размера примерно так же дорого, как полный сборщик мусора, и поэтому, вероятно, это не вариант. В некоторых языках JVM (clojure?) Вы можете теоретически убедиться, что на объекты в кэше не будут ссылаться внешние объекты, а затем вы сможете отслеживать реальный размер кэша.

0 голосов
/ 27 марта 2009

То, что делает эту работу, является java.lang.ref.SoftReference. Обычно вы расширяете класс SoftReference, чтобы подкласс содержал ключ.

0 голосов
/ 27 марта 2009

Если вы не можете сделать какие-либо оценки - напишите политику удаления кэша, которая сбрасывается на основе размера кучи JVM (опрашивается из System) или вызывается вызовом finalize () - из-за потерянного объекта (в GC).

0 голосов
/ 27 марта 2009

Помимо предположения об использовании памяти объектом, для разумного алгоритма вам также необходимо угадать стоимость его воссоздания. Разумным предположением будет стоимость отдыха, примерно пропорциональная объему памяти. Таким образом, факторы нейтрализуют друг друга, и вам не нужно ни того, ни другого. Простой алгоритм, вероятно, сработает лучше.

0 голосов
/ 27 марта 2009

Это не просто сложно измерить - это сложно определить.

Предположим, что две записи в кэше ссылаются на одну и ту же строку - учитывают ли они обе размер этой строки, несмотря на то, что удаление одной из них из кэша не сделает строку пригодной для сбора мусора ? Ни один из них не считает размер, несмотря на тот факт, что если оба из них будут удалены из кэша, строка может быть пригодна для сбора? А что если другой объект, отсутствующий в кэше, имеет ссылку на эту строку?

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

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