Сокращение использования памяти очень большого HashMap - PullRequest
0 голосов
/ 18 июля 2011

У меня есть очень большая хэш-карта (более 2 миллионов записей), которая создается путем чтения содержимого файла CSV. Некоторая информация:

  1. HashMap отображает ключ String (который составляет менее 20 символов) в значение String (которое составляет приблизительно 50 символов).
  2. Этот HashMap инициализируется с начальной емкостью 3 миллиона, так что коэффициент загрузки составляет около 0,66.
  3. HashMap используется только одной операцией, и как только эта операция завершена, я «очищаю ()» ее. (Хотя это не похоже на то, что эта очистка на самом деле очищает память, нужен ли отдельный вызов System.gc ()?).

Одна идея, которая у меня возникла, состояла в том, чтобы изменить HashMap на HashMap и использовать в качестве ключа хэш-код String, это в конечном итоге сэкономит немного памяти, но рискует столкнуться с коллизиями, если две строки имеют идентичные хэш-коды ... скорее всего это для строк длиной менее 20 символов?

У кого-нибудь еще есть идеи о том, что здесь делать? Размер самого CSV-файла составляет всего 100 МБ, но java использует более 600 МБ памяти для этой HashMap.

Спасибо!

Ответы [ 4 ]

1 голос
/ 02 апреля 2012

то, что вы пытаетесь сделать, это в точности операция JOIN. Попробуйте рассмотреть БД в памяти, например, H2, и вы можете достичь этого, загрузив оба CSV-файла во временные таблицы, а затем выполните JOIN поверх них. И, по моему опыту, h2 отлично работает с операцией загрузки, и этот код, безусловно, будет быстрее и потребляет меньше памяти, чем ваш метод соединения на основе HashMap.

1 голос
/ 18 июля 2011

Анализ CSV и создание карты, ключи которой являются вашими существующими ключами, но значения являются целочисленными указателями на места в файлах для этого ключа.

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

0 голосов
/ 18 июля 2011

Похоже, у вас уже есть рамки, чтобы попробовать это.Вместо добавления строки добавьте string.hashCode() и посмотрите, не возникнут ли коллизии.

С точки зрения освобождения памяти JVM обычно не уменьшается, но при необходимости собирает мусор.

Кроме того, похоже, что у вас может быть алгоритм, которому вообще не нужна хеш-таблица.Не могли бы вы описать, что вы пытаетесь сделать, немного подробнее?

0 голосов
/ 18 июля 2011

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

...