2014-12-24 2 views
-1

Мне нужно просматривать около 3000 папок, каждая папка содержит 300 файлов CSV.Чтение файлов: ошибка в памяти

Это ошибка, которая происходит на линии, а ((nextLine=csvReader.readNext()) != null):

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded 
    at au.com.bytecode.opencsv.CSVParser.parseLine(CSVParser.java:206) 
    at au.com.bytecode.opencsv.CSVParser.parseLineMulti(CSVParser.java:174) 
    at au.com.bytecode.opencsv.CSVReader.readNext(CSVReader.java:237) 
    at DA.readTelemetryData(DA.java:78) 
    at DA.main(DA.java:24) 

Вопрос заключается в том, как решить эту проблему? Почему это происходит и что не так в моем коде?

Здесь я приведу код:

private static HashMap<Integer,HashMap<Integer,List<double[]>>> readTelemetryData() throws Exception 
    { 
     HashMap<Integer,HashMap<Integer,List<double[]>>> xy_total = new HashMap<Integer,HashMap<Integer,List<double[]>>>(); 

     for (int i=0; i<Constants.MAX_FOLDERS; i++) 
     { 
      HashMap<Integer,List<double[]>> xy_total_per_folder= new HashMap<Integer,List<double[]>>(); 
      for (int j=0; j<Constants.MAX_FILES_INSIDE_FOLDER; j++) 
      {    
       CSVReader csvReader = null; 
       File f = new File("data/"+ (i+1) +"/"+ (j+1) +".csv"); 
       if(f.exists()) 
       { 
        csvReader = new CSVReader(new FileReader(f)); 
        List<double[]> xyArr = new ArrayList<double[]>(); 
        String[] firstLine=csvReader.readNext(); 
        if (firstLine != null) 
        { 
         String[] nextLine=null; 
         while ((nextLine=csvReader.readNext()) != null) 
         { 
          double[] d = new double[2]; 
          d[0]=Double.parseDouble(nextLine[0]); 
          d[1]=Double.parseDouble(nextLine[1]); 
          xyArr.add(d); 
         } 
        } 

        xy_total_per_folder.put(j, xyArr); 

        csvReader.close(); 
       } 
      } 
      xy_total.put(i, xy_total_per_folder); 
     } 
     return xy_total; 
    } 
+0

В чем вы сомневаетесь? – talex

+0

@talex: Вопрос в том, как решить эту проблему? Почему это происходит и что не так в моем коде? Я предполагаю, что мне следует избегать использования HashMap, но я не уверен. –

+2

У вас код в порядке.Если вам нужны все эти данные, это одно простое решение. Увеличьте предел памяти. запустить java с '-XMX = 1G' – talex

ответ

2

Вы работаете из памяти.

HashMap<Integer,V> - довольно плохой выбор. Для ключа требуется 16 байт и, вероятно, 24 байта для каждой записи + мертвое пространство. Затем вашему double[] требуется 32 байта (для хранения 16 байтов полезной нагрузки). В списке массивов вам нужны еще 4 байта для справки ...

Таким образом, каждая строка будет стоить вам 36 байт, например, 16.

Рассмотрите возможность использования более компактных структур данных. GNU Trove - это библиотека, предлагающая большие коллекции для примитивных типов; но не стоит недооценивать значение массивов ...

Для обработки большого количества примитивных типов (int, double и т. д.) держаться подальше от java.util. коллекций. Вместо этого потратьте дополнительное время на организацию своей памяти.

Например, вы могли бы использовать Trove-х TDoubleArrayList, один для всех х и один для все то у значения, вместо того, чтобы использовать один массив для каждой строки. По завершении чтения файла вы можете преобразовать их в минимальные double[] x; double[] y; массивы и повторно использовать TDoubleArrayList для разбора следующего файла.

И последнее, но не менее важное: Java по умолчанию использует только 25% вашей памяти. используйте -Xmx, чтобы увеличить лимит.

Запуск профайлера памяти. Где большая часть выделенной памяти? Все это необходимо? Возможно, этот CSVReader использует утечку памяти! Использование профайлера памяти - это простой способ узнать.

Но сделайте математику. Сколько у вас линий - может вы поместили их все в память?

0

Существует правило, две причины такого поведения:

  1. утечка памяти. Это означает, что вы сохраняете данные в магазине, которые больше не нужны. Анализ дампа памяти для исправления.

  2. Недостаточно памяти, потому что вам на самом деле нужна такая память. Йо просто может дать ему больше памяти. Или попробуйте изменить алгоритмы и структуры данных.

Смежные вопросы