Мне нужно быстро найти объект, используя как можно меньше памяти. Какой контейнер данных я должен использовать?

Моей программе нужно вставить более миллиона записей в контейнер данных. Я пробовал hashmap и treemap. И то и другое даст мне исключение пространства кучи, хотя я позволю JVM использовать оперативную память 2 ГБ.

Моя программа часто получает конкретные данные из контейнера, которые, я думаю, если это займет O(logn) время, будут приемлемы для меня. Так какой контейнер я должен использовать? Или мне нужно реализовать один? Как?

Больше подробностей: ключ является String, как глобальный идентификатор, например, "00011123459", что-то вроде этого. Тогда ключ отобразится в список списка, т.е. List<List<String>>, Моя программа считала строку из файла, затем изменила строку на список, затем получила глобальный идентификатор из списка, затем поместила список в соответствующий список списка. Файл содержит более миллиона строк, поэтому я считаю, что основная причина в том, что я создаю слишком много списков. Тем не менее, я не могу добавить больше памяти на машину.

4 ответа

Предполагая, что подавляющее большинство использования памяти связано с самими данными записи, может случиться так, что выбор контейнера не решит вашу проблему (в качестве теста попытайтесь загрузить все ваши данные в массив; если вы закончили памяти, вам понадобится другое решение). Мало того, но если вы урезаете его настолько близко к емкости, у вас все равно будут проблемы, если в будущем вы столкнетесь с большим количеством записей.

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

  • Храните свои записи в надлежащей базе данных (многие варианты здесь, SQLite может быть наиболее удобным для вас - много вариантов для доступа, начиная от прямой java.sql.* в спящий режим).
  • Используйте что-то вроде MapDB, как отметил Андрей Чащев.
  • Если ваша программа часто обращается к небольшому подмножеству данных или последовательно обращается к одним и тем же данным, рассмотрите возможность оставлять записи на диске, находить их при необходимости и кэшировать их при обнаружении (поиск только на диске, если интересующая запись не находится в кэше).
  • Вместо того, чтобы хранить целые записи на карте, возможно, храните некоторую информацию, которая поможет вам быстрее находить их на диске и лениво загружать записи по мере необходимости (например, сохранять смещение файла данных записи на карте, затем при поиске загружать фактические данные записи из файл, реализовать кеширование при желании).

Лично я бы выбрал первый вариант (обязательно создайте индекс по ключам, которые вы обычно используете для поиска записей), поскольку его очень просто настроить и использовать, а SQLite (например) автономен и требует нет сервера. Ценой дополнительной сложности разработки вы все еще можете кэшировать данные, если обнаружите, что ваши требования к производительности не выполняются или что-то вроде Hibernate сделает это за вас.

HashMap занимает меньше памяти, чем TreeMap и является O(1).

Если ваши ключи цифры, вы можете сэкономить память с TLongObjectHashMap от Trove4j.

Другой вариант - временно сохранить ваши данные на диске с помощью MapDB.

Вы также можете применить кеширование с CacheBuilder в Гуаве: что происходит, когда коллекция в Java увеличивается до предела?

Если у вас есть больше поддержки инфраструктуры, попробуйте увеличить объем памяти до 4 или 5 ГБ и использовать любую из этих карт

  1. Использовать древовидную карту - если вы хотите, чтобы ваши объекты были отсортированы. Поскольку объекты сортируются, требуется дополнительное время для сортировки всей карты после вставки нового объекта.

  2. Используйте Hash map - для быстрого добавления / поиска, поскольку объекты не сортируются.

Из Javadoc.

This implementation provides guaranteed log(n) time cost for 
the containsKey, get, put and remove operations.

Так что используйте TreeMap и дайте Java больше памяти.

Другие вопросы по тегам