Кэширование объектов в памяти в java

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

  1. Каждая запись/объект связана с уникальным ключом.
  2. 400-500 записей/объектов для хранения. Если количество записей превысит указанный лимит, старые записи следует удалить.
  3. Записи не должны храниться более 2 минут.
  4. Должен уменьшаться, когда JVM не хватает памяти (вид слабой ссылки).
  5. Стороннюю библиотеку нельзя использовать, потому что это небольшой модуль, и цель состоит в том, чтобы просто уменьшить ненужный доступ к сети.
  6. Больше пишет, меньше читает

Здесь также важна безопасность, потому что мы собираемся кэшировать некоторые конфиденциальные данные. Эти данные будут кэшироваться в памяти. Должен ли я действительно беспокоиться о безопасности и шифровать данные?

Я ищу класс Java, который обеспечивает аналогичную функциональность.

В настоящее время я думаю о расширении WeakHashMap и реализации различных частных/общедоступных методов для соблюдения требований.

Если у вас есть другая идея, пожалуйста, поделитесь здесь.


person Rakesh    schedule 18.09.2012    source источник
comment
Third party library shouldn't be use. Странное требование..   -  person Brendan Long    schedule 18.09.2012
comment
@БренданЛонг прав. CacheBuilder Guava будет отличное решение этой проблемы.   -  person condit    schedule 18.09.2012
comment
Если вам поручили повторно реализовать это конкретное колесо, и вы задаете эти вопросы, значит, что-то пошло не так.   -  person Dave Newton    schedule 18.09.2012
comment
@Brendan На самом деле отсутствие сторонних библиотек - ОЧЕНЬ распространенное требование, с которым я сталкивался в проектах в корпоративном мире.   -  person Brian Knoblauch    schedule 18.09.2012
comment
Многие корпоративные магазины не будут использовать решения с открытым исходным кодом, потому что они считают, что это подвергает их ответственности в случае, если разработчики решения используют его для плагиата.   -  person Dexygen    schedule 18.09.2012
comment
С редактированием (5) имеет для меня еще меньше смысла. Почему вы хотите увеличить свой небольшой модуль, включив код для чего-то, что уже сделано (лучше)?   -  person Brendan Long    schedule 18.09.2012


Ответы (3)


Вы не хотите использовать WeakHashMap. SoftHashMap было бы ближе, но его нет в стандартной библиотеке. На вашем месте я бы посмотрел классы кеша Guava для подсказок.

Но вот несколько дополнительных мыслей:

Должен уменьшаться, когда JVM не хватает памяти (вид слабой ссылки).

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

Не следует использовать сторонние библиотеки.

Все говорили об этом, и они правы.

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

person Enno Shioji    schedule 18.09.2012

Нет, вы не должны этого делать. WeakHashMap не является кешем!

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

...

Так как же, черт возьми, мне реализовать кеш в Java?

Я предлагаю использовать одну из свободно доступных реализаций кэша, например JCS, OSCache и другие . Эти библиотеки обеспечивают лучшее управление памятью с помощью политик LRU и FIFO, например, переполнение диска, истечение срока действия данных и многие другие дополнительные дополнительные функции.

Как упоминает @user463324, вы должны просто использовать библиотеку, которая уже реализует это, например Google Guava, который входит в состав Apache 2.0. лицензия, с которой ни у одного здравомыслящего бизнеса не возникло бы проблем. Придумано не здесь — это не повод игнорировать решение.

person Brendan Long    schedule 18.09.2012

У вас есть два варианта: JCS или Memcache/EHCache.

Эти два варианта функционально эквивалентны, но имеют некоторые важные различия. При использовании JCS кэшированные объекты не сериализуются/десериализуются. Они остаются объектами Java, поэтому их хранение и извлечение выполняется очень быстро. Однако это означает, что ваш кеш находится внутри JVM, следовательно, использует кучу JVM, а также недоступен для других JVM. [JCS предоставляет некоторый тип распределенных возможностей в качестве дополнения].

С другой стороны, Memcache/Ehcache — это внешние кэши, которые выполняют сериализацию/десериализацию при выполнении операций размещения/получения. Это может свести на нет преимущества кэширования в некоторых крайних случаях. поэтому бенчмаркинг для скорости имеет важное значение. Если подходит, то раздается, использует свою память, может быть и на другом ящике. Но это также означает, что вы должны учитывать безопасность данных между JVM и внешним кешем.

person srini.venigalla    schedule 18.09.2012
comment
OP специально сказал, что сторонняя библиотека не может использоваться - person Raedwald; 30.01.2014