ArrayList <ArrayList <String>> выполняется вне памяти (пространство кучи Java). Любой другой вариант? - PullRequest
3 голосов
/ 20 апреля 2011

Я работаю с Структура данных ArrayList для работы с файлом cvs.Моя машина довольно мощная: Память: 8 ГБ ОЗУ процессора: 4 ЦП, каждое i5 Intel Core 2.5 ГГц

В eclipse я назначил -Xmx5120m (5 ГБ ОЗУ для java vm) с помощью панели аргументов vmв Run as-> Конфигурация.

Я все еще получаю «вне памяти кучи Java» для моего ArrayList<ArrayList<String>>, если оно больше, чем 468000 X 108. Я использую arraylist, потому что я чувствую себя наиболее комфортно с ним, и это облегчает обработкуданные для моей цели.

На самом деле, я использую этот двумерный массив для контекста на основе столбцов, например

arraylist.get(i).get(0) 

, где

0 < i < 468000 

будет представлять один столбец.Поскольку я выполняю такие операции, как (замена столбца другим столбцом, копирование столбца, вставка столбца в произвольную позицию в arrayList и т. Д.), Я мог думать только о arrayList, потому что он амортизировал постоянное время для добавления или вставки вarraylist в его среднем случае.

Итак, теперь мой вопрос:

Какие другие структуры данных я мог бы использовать вместо arraylist, чтобы достичь величины, значительно превышающей 468000 X 108 (например,например (833 * 1000000) X 108) и сможете ли выполнять все операции, о которых я упоминал выше?(но я все еще хочу быть в состоянии сделать это на моей машине, используя имеющуюся у меня емкость)

Я мог бы подумать о том, чтобы делать все это последовательно, то есть сначала обработать 468000 X 108 и записать его в CSVфайл, а затем снова загрузить его в архиватор 468000 X 108 и записать его в другой файл и т. д. *

Не думаю, что я достиг предела массива для моего архива.

Буду признателен за любую помощь.

Ответы [ 3 ]

4 голосов
/ 20 апреля 2011

Вы пытаетесь вставить файл с 468 000 строк в 5 ГБ памяти, и у вас недостаточно памяти.

Структура данных не является проблемой.

Вам нужно изменить свой подход, а не делать это.Одновременно обрабатывайте куски файла, извлекайте только те данные, которые вам нужны, и т. Д.

1 голос
/ 20 апреля 2011

Вставка куда-нибудь в ArrayList не даст вам амортизированное постоянное время, так как список придется копировать изнутри - это будет работать только до тех пор, пока вы вставите в конец.

Кроме того, когдаArrayList должен увеличиваться, он будет вычислять новый размер на

  int newCapacity = (oldCapacity * 3)/2 + 1;

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

Пока вам нужно всего несколько столбцов за раз, я бы предложил хранить каждый столбец в отдельном файле,который вы можете загружать / записывать по требованию - если они будут содержать только строки, вы можете подумать о некотором легко читаемом двоичном формате и использовать, например, DataOutputStream и -InputStream.Вставка столбца просто стала бы операцией переименования файла ... Вы также можете добавить некоторое кэширование, чтобы сохранить самые последние или наиболее часто используемые столбцы в памяти (найдите java.util.LinkedHashMap, чтобы получить представление о простом LFU-кеше).Не используйте базу данных, если вам не нужны транзакции или тому подобное, не храните такие данные в подробном формате, таком как XML - в противном случае вы получите огромную потерю производительности.

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

0 голосов
/ 20 апреля 2011

Хороший способ «изменить свой подход», как предлагали другие, - сохранить ваши данные в базе данных или XML-файле, а затем работать с небольшими подмножествами этих данных по мере необходимости.

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