Проблема с пространством хэш-карты - PullRequest
2 голосов
/ 29 марта 2012

В моем Java-коде я использую Multimap Guava ( com.google.common.collect.Multimap ), используя это:

 Multimap<Integer, Integer> Index = HashMultimap.create()

Здесь ключ Multimap - это некоторая частьURL и значение - это другая часть URL (преобразованная в целое число).Теперь я назначаю пространство кучи JVM 2560 МБ (2,5 ГБ) (используя Xmx и Xms).Тем не менее, он может хранить только 9 миллионов таких (ключ, значение) пар целых чисел (около 10 миллионов).Теперь проблема в том, что я могу предоставить JVM только ограниченный объем памяти (скажем, 2 ГБ).

Итак, кто-нибудь может мне помочь,

1) Есть ли другой способ или домашнее решение?решить эту проблему с памятью?Значит, Multi-Map на основе диска / БД может быть хорошим решением?Я прочитал из некоторых веб-статей, что есть какое-то решение на основе БД / Диска для решения этой проблемы, например. Berkley DB или Ehcache .Кто-нибудь может сообщить мне, является ли (или какой) быстрее?

2) Есть ли проблемы с производительностью (основанные на дисках / БД Multi-Map) (я прошу как для сохранения, так и для поиска)?

3) Любая идея или информация, как их кратко использовать.

4) Для меня подойдет любая другая идея.

Примечание: я хочу решение Multimap (ключ может иметь несколько значений) для решения вышеуказанной проблемы.И я должен учитывать производительность хранения и поиска.

Ответы [ 2 ]

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

JDBM3 - это очень быстрая на диске библиотека HashMap / TreeMap (B + Tree), которая, как утверждают, в 4 раза быстрее, чем Беркли дБ Миллиарды записей могут быть сохранены на карте. Он выполняет внутреннее кэширование, поэтому операции с картами не будут замедляться из-за доступа к диску.

DB db = DBMaker.openFile(fileName).make();
Map<Integer,Integer> map = db.createHashMap("mapName");
map.put(5, 10);
db.close()

У него нет Multimap, но значением может быть Set / List.

1 голос
/ 30 марта 2012

Вы, конечно, не будете хранить 100 миллионов пар Integer объектов в 2,5 ГБ памяти. Если я не ошибаюсь, Integer будет использовать как минимум 16 байтов памяти в Oracle / Sun JVM (и выравнивание также составляет 16 байтов), что означает 3,2 ГБ памяти только для Integer без каких-либо структура.

При таком размере данных вы обязательно должны использовать что-то, что поддерживается диском, или использовать сервер с большим объемом памяти и / или оптимизированными структурами данных (в частности, старайтесь избегать оболочек примитивного типа). Я использовал H2 для подобных задач и нашел его довольно хорошим (он может использовать сопоставленные файлы для доступа к диску вместо чтения), но у меня нет никакого сравнения с другими подобными библиотеками.

...