ошибка из памяти при добавлении hashmap и arraylist

1

У нас большие данные в csv файле. Он имеет 2,5 миллиона строк, и каждая строка имеет 10 полей, и мы пытаемся подготовить хэш-карты для каждой строки, а затем добавим этот хэш файл для arraylist.

Я не могу этого сделать из-за огромных данных, которые он выбрасывает из памяти ошибку Java Heap space.

Но моему приложению нужен список hashmap (я не хочу увеличивать heapspace).

reader = new CSVReader(new FileReader(dataFile),',');
         Map<String, String> feedMap = null;
         String[] firstLine;
         String[] nextLine;
         String mappingKey = null;
         String mappingValue = null;
         //Read one line at a time
         firstLine = reader.readNext();
         while ((nextLine = reader.readNext()) != null){
             int i = 0;
             feedMap = new HashMap<String, String>();
             for(String token : nextLine){
                 mappingKey = xmlNodeMap.get(firstLine[i]);                     
                 if (mappingKey != null) {
                     mappingValue = token.trim().length() > 0 ? token : Constants.NO_VALUE;
                     feedMap.put(mappingKey, mappingValue);
                }
                i++;
        }                
       listOfMaps.add(feedMap);
 }
  • 4
    Ну, чтобы хранить много данных в памяти, вам нужно много памяти. Поэтому он либо обрабатывает запись данных по записи, либо сохраняет все это в памяти и увеличивает кучу. Там тоже нет бесплатного обеда.
Теги:
arraylist
hashmap
out-of-memory

3 ответа

2

Это может показаться проблесковым, но ваша проблема в том, что вашему приложению нужен список из 2,5 миллионов строк в виде HashMaps.

Это абсурдное, необоснованное и откровенно смешное требование; Я не могу себе представить, какую пользу будет использовать такая структура данных.

Измените приложение, чтобы оно не требовалось.

  • 0
    Ну, в конце концов мы разделили файлы на 10000 строк в каждой на основе общего размера файла. Затем мы добавили карту для каждого отдельного файла и обработали в db, используя список файлов.
0

Вы можете попробовать использовать байт [] вместо объекта String: byte[] key = mappingKey.getBytes("UTF-8")

Каждый объект String содержит набор символов UTF-16. В большинстве случаев это означает 2 байта на символ. Кодировка UTF-8 использует один байт для ASCII, два байта для многих языков Европы.

Также каждый объект String содержит ссылку на массив символов. Это означает, что у вас есть два объекта в куче памяти: String и char. Каждый объект (даже просто new Object()) стоит ~ 24 байта (это зависит от версии Java VM и опций).

Таким образом, вы можете легко уменьшить количество объектов в два раза (один байт [] вместо пары String + char []), а длина массива символов UTF-8 обычно меньше длины символов UTF-16.

0

Полностью согласен с богемским ответом.

Чтобы помочь вам, я предлагаю, чтобы вместо того, чтобы читать один раз файл и хранить все в памяти, вы читаете его один раз, сохраняете "карту индексов" (в зависимости от ваших потребностей). Затем, когда вам нужно провести исследование вашего файла, вам придется снова открыть поток и использовать свою "карту индексов" для оптимизации времени, затраченного на поиск.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню