Я читаю много XML-файлов в java и преобразовываю их в JSON и записываю их обратно в файловую систему. Общий размер папки XML составляет около 100 ГБ, а размер одного файла XML может составлять около 100 МБ. Размер JVM-памяти установлен 512 МБ. Вот цикл для чтения и записи файлов:Исключение в потоке «main» java.lang.OutOfMemoryError
for(int i=0; i<fileNames.size(); i++) {
try{
File f = new File(File.separator+fileNames.get(i));
BufferedReader br = new BufferedReader(new FileReader(f));
String line;
StringBuilder sb = new StringBuilder();
long startTime = System.nanoTime();
while((line=br.readLine())!= null){
sb.append(line.trim());
}
String jsonData = XML.toJSONObject(sb.toString()).toString(0);
String outputFilename = fileNames.get(i).split("\\.")[0]+".json";
Path jsonFilePath = new Path(jsonPath+File.separator+outputFilename);
FSDataOutputStream out = fileSystem.create(jsonFilePath);
out.writeChars(jsonData);
byte[] b = jsonData.getBytes("UTF-8");
out.close();
br.close();
long endTime = System.nanoTime();
double executionTime = (double)(endTime - startTime)/1000000000.0;
System.out.println("Input file : "+fileNames.get(i)+" - "+(double)(f.length()/1000) + " kb");
System.out.println("Output file : "+outputFilename+" - "+(double)(b.length/1000) + " kb"+" in "+executionTime + " seconds");
System.out.println("--------------------------------------------------");
}catch(IOException ioe){
ioe.printStackTrace();
}catch (JSONException je) {
System.out.println(je.toString());
}catch(Exception e){
e.printStackTrace();
}
}
После запуска в течение некоторого времени эта программа кидает: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
, если я увеличить JVM памяти -Xmx1024 программа работает очень медленно, и процесс Java потребляет много памяти. Поскольку я создаю файл, stringbuilder и bufferedreader в for loop, они находятся в памяти, и они не собираются с мусором. Как я могу заставить этот код работать. Благодаря
Вы можете попробовать использовать несколько потоков, проходящих параллельно. Каждый поток работает в разных файлах, поэтому они не будут мешать друг другу. Это, конечно, требует большего использования памяти – gerrytan
Можете ли вы проверить, является ли проблема единственным файлом? Перемещение 'System.out.println()' для входного файла перед обработкой должно указывать, какой файл последний, когда происходит OOM; затем изменение кода для запуска только в том, что один файл скажет, является ли это проблемой одного файла или что-то еще. – ash