我正在阅读大量java中的xml文件,并将它们转换为json并将它们写回文件系统。xml文件夹的总大小约为100gb,单个xml文件的大小约为100mb。jvm内存的大小设置为512mb。以下是用于读取和写入文件的循环:
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进程会消耗大量内存。因为我在for循环中创建file、stringbuilder和bufferedreader,所以它们都在内存中,不会被垃圾收集。我怎样才能使这个代码工作。谢谢
2条答案
按热度按时间h9vpoimq1#
仔细看代码,没有明显的内存泄漏,因此问题很可能是由于单个输入文件太大而无法处理造成的。
如果jvm堆大小超过服务器上的可用内存,那么将jvm堆大小设置为1024可能会运行得非常慢,因为这会导致交换,即磁盘i/o,而且非常慢。
消除单个输入文件(使用相同的硬件)引起的问题的唯一方法是以某种使用较少内存的方式更改处理。例如,使用一个使用较少内存的xml到json转换工具,或者找到一种方法将xml拆分成多个片段并重新组合起来;这可不是小事。
你可以转向更大的硬件。如果可能,请确保使用64位o/s和64位版本的java。
e4yzc0pl2#
我想有些事情你可以试试
如果我没记错的话,可以手动调用垃圾收集器system.gc()。
您可以使用探查器(如netbeans提供的那样)查看内存泄漏的位置。
你也可以查看弱引用/幻象引用,但我对它们的了解很少。