| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Выбор коллекции для 300000 тысяч строк! |
| Автор: freshAngel 9.12.2009, 18:04 | ||
| Привет. Какую коллекцию лучше выбрать, что - бы хранить 300000 строк!? Сейчас:
Собственно будет храниться 300000 ArrayList'ов в векторе. Сейчас все это тормозит ужасно!!! -Xms1024m -Xmx1024m не помогает... |
| Автор: Kircul 9.12.2009, 18:12 |
| ИМХО, в таком случае проще использовать БД |
| Автор: freshAngel 9.12.2009, 18:14 | ||||||
При использовании БД тормозит еще хуже... Поэтому перешел на хэш. Беру кусок из БД и записываю его в хэш, а дальше прогоняю циклами, if'ми... Добавлено @ 18:15
Нажимаю кнопку "Найти" в этот момент заполняются вектора и происходит их обработка, далее жду минут сорок, пока не вывалится ексепшн: memory heap size... |
| Автор: Kircul 9.12.2009, 18:18 |
| Ну попробуй LinkedList использовать, если заранее не известен размер коллекции, в противном случае в конструкторе укажи кол-во элементов. |
| Автор: freshAngel 9.12.2009, 18:28 |
| Можно попробовать, только вот добавление в конец быстрей в ArrayList и рандомный поиск элементов быстрей в ArrayList вместе с сортировкой. А LinkedList быстрей только при добавлении в начало... Есть еще варианты!? |
| Автор: LSD 9.12.2009, 18:28 | ||
Что означает, что памяти все таки нехватает и дело не в том, какая коллекция используется. По сравнению с размером данных, накладные расходы на саму коллекцию пренебрежимо малы. Надо или увеличить объем памяти, или как-то оптимизировать объемы данных. Добавлено через 1 минуту и 44 секунды На больших объемах LinkedList будет тратить больше памяти на один элемент. |
| Автор: freshAngel 9.12.2009, 18:32 | ||||||
Как можно оптимизировать!? Что можно сделать со строкой!? У меня в коде очень много сверок в условиях с equals и регулярными выражениями, вот пример кода:
|
| Автор: Kircul 9.12.2009, 18:36 | ||
На сколько я знаю ArrayList это только обертка на массив и при превышении размера созданного массива происходит создание нового с большим размером и копирование в него всех елементов. А при использование LinkedList каждый раз выделяется место только для одного элемента и он линкуется к уже созданной коллекции. Я где-то заблуждаюсь? Т.е. до срабатывания сборщика мусора мы имеем кучу засоренной памяти. Вероятно это так же как и при конкатенации строк при помощи + или StringBuffer |
| Автор: LSD 9.12.2009, 19:06 | ||||
Скорее всего общих советов, будет недостаточно, надо разбираться с конкретным случаем отдельно. Если много дупликатов строк, можно их интернировать. Можно загрузить часть строк, обработать, записать промежуточные результаты в базу/файл, загрузить следующую партию и т.д. Вообщем надо смотреть на конкретный код.
Все так, но давай посчитаем (для 32-х битной JVM):
LinkedList же на больших объемах, тратит на каждый элемент 20 байт.
Перед тем как будет выкинут OutOfMemoryError, всегда вызывается сборщик мусора. Так, что в данном случае не это вызывает проблему. |
| Автор: v2v 9.12.2009, 19:14 | ||||
а else есть ? нет? зачем выбирать из базы записи если вы их потом отфильтровываете? возможно стоит пересмотреть условия по которому запись заноситься в коллекцию и уже на этом этапе выбрасывать не нужные записи? |
| Автор: Kircul 9.12.2009, 19:19 | ||||
Так-то оно так, но если взять такой код
То на моей машине (параметры запуска дефолтные) при INITIAL_CAPACITY = 15000000 валится OutOfMemoryError (где-то на кол-ве в 7600000), но если поставить INITIAL_CAPACITY в аргументы конструктора то все работает нормально, при INITIAL_CAPACITY = 16000000 валится в обоих случаях. Т.е. при указании правильного кол-ва в аргументы конструктора мы выигрываем в 2 раза больше памяти. При использовании LinkedList падает ошибка и на 7600000. Есть информация к размышлению... |
| Автор: ivanovpv 9.12.2009, 21:25 | ||||
Конечно же надо ставить все это безобразие на БД, индексировать строки и обращаться через нормальные select'ы... - типа:
Ну решите вы сейчас на 300 тыс. строк, а если будет 300 миллионов строк? Никакого хипа не хватит и никаких коллекций Операция equals() на String'е очень дорогая операция знаете ли... А любая нормальная СУБД справится с select'ом на 300 тыс. записей за доли секунды - отвечаю Так что подумайте что лучше сидеть перед монитором 40 минут в ожидании OutOfMemory или перенести все в БД и написать через JDBC интерфейс и получать результаты за секунды. |
| Автор: serger 10.12.2009, 10:26 |
| Посмотри вариант Bercley DB Специально для больших хэшей - сомневаюсь, что свой велосипед будет много лучше... http://ru.wikipedia.org/wiki/Berkeley_DB http://www.oracle.com/technology/products/berkeley-db/index.html |
| Автор: LSD 10.12.2009, 14:34 | ||||||
Информация то конечно, есть. Но тут надо учитывать таку вещь как особенности работы Java со строками. В твоем случае, у тебя всего один екземпляр строки, с таким же успехом можно инициализировать коллекцию null-ами. Вот более коплексный пример с одинаковыми, разными и вообще нулевыми строками:
Запускать с ключем: -Xmx128M -Xms128M Результат:
Видно, что результаты со статичной строкой и нулевой практически идентичны. А вот когда уже речь идет о реальных данных, там разница между коллекциями не так заметна, сказывается, что основную часть памяти потребляют объекты. |