HashMap на Java, 100 миллионов записей - PullRequest
27 голосов
/ 02 ноября 2010

Я хочу сохранить 100 миллионов терминов и их частоты (в текстовой базе данных) в HashMap <String, Double>. Это дает мне ошибку «Недостаточно памяти». Я пытался увеличить кучу пространства до -Xmx15000M. Однако он работает полчаса, затем снова выдает то же исключение. Размер файла, из которого я пытаюсь прочитать слова и частоты, составляет 1,7 ГБ.

Любая помощь будет высоко ценится.

Спасибо :-)

Ответы [ 15 ]

0 голосов
/ 15 апреля 2013

оборотная сторона конверта: 1.7Gb / 100M = средние 18 байтов = за семестр и частота

Мы можем использовать хеш-карту, закодированную вручную, подкрепленную двумя логическими массивами.

  1. Один для хранения int частот (значений), а другой - для построения массива символов стиля C для имитации двумерного массива c (массива массивов символов). поэтому мы индексируем расчетным путем. мы не можем использовать двухмерный массив Java, поскольку он содержит слишком много служебных данных. Этот массив символов может содержать массив символов фиксированного размера для представления ключей. Таким образом, мы вычисляем хеш ключа и помещаем его в этот «двумерный массив», и если у нас есть конфликт, он может быть разрешен, скажем, линейным зондированием. Пары ключ и значение связаны общим индексом массивов.

  2. Хэш-карта должна использовать открытую адресацию, поскольку у нас недостаточно памяти для объединения в цепочку.

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

  4. Используемое пространство = 2 степени 29 для массива int + (2 степени 4 (16 байт на строку) * 2 pow 27) = 3,5 гигабайта

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

0 голосов
/ 03 ноября 2010

Есть интересное предложение от Terracotta - BigMemory , которое, кажется, именно то, что вы хотите.Я сам не пробовал и не знаю условий лицензирования и т. Д.

0 голосов
/ 03 ноября 2010

Попробуйте заменить его на cdb . До 4 ГБ и:

Для успешного поиска в большой базе данных обычно требуется всего два обращения к диску. Неудачный поиск занимает только один.

0 голосов
/ 02 ноября 2010

Это плохой дизайн. Имея 1,7 ГБ данных в памяти на HashMap, я бы сделал одно из двух:

  1. Сохраните все данные (файл / база данных) и поместите 1% или что-то в памяти Используйте некоторый алгоритм для определения, какие идентификаторы будут в памяти и когда.

  2. Использовать memcached . Самый простой выход. Распределенный в памяти хэши. Это именно то, для чего используются DHT.

0 голосов
/ 02 ноября 2010

По той причине, что это не помогло, я согласен с приведенными выше ответами.

БД - хороший выбор. Но даже на коммерческом уровне БД они также предложили бы «Разделение» данных для выполнения эффективных действий..

В зависимости от вашей среды, я мог бы предложить распределить ваши данные по нескольким узлам, которые подключены через LAN.Основываясь на значении ключа,

Узел 01 имеет ключ, начинающийся с 'a' Узел 02 имеет ключ, начинающийся с 'b' ....

Таким образом, ваша программа внезапно переключилась на сетевое программирование ..

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