“线程中的异常”;“主要”;java.lang.OutOfMemoryError
我正在阅读大量java中的XML文件,并将它们转换为JSON,然后将它们写回文件系统。XML文件夹的总大小约为100Gb,单个XML文件的大小约为100MB。JVM内存的大小设置为512Mb。以下是用于读取和写入文件的循环:“线程中的异常”;“主要”;java.lang.OutOfMemoryError,java,exception,hadoop,Java,Exception,Hadoop,我正在阅读大量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 = ne
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();
}
}
for(inti=0;i我想有些事情你可以试试
如果我没记错的话,可以手动调用垃圾收集器System.gc()
您可以使用探查器(与Netbeans一起提供)查看内存泄漏的位置
您也可以查看弱引用/幻影引用,但我对这些方面的知识不多
仔细查看代码,没有明显的内存泄漏,因此问题可能是由于单个输入文件太大而无法处理所致
如果JVM堆大小超过服务器上的可用内存,那么将JVM堆大小设置为1024可能会运行得非常慢,因为这会导致交换,即磁盘I/O,速度非常慢
消除单个输入文件(使用相同的硬件)引起的问题的唯一方法是以某种使用更少内存的方式更改处理。例如,使用使用使用更少内存的xml到json转换工具,或者找到一种方法将xml拆分为多个部分并重新组合在一起;但这并不简单
您可以移动到更大的硬件。如果可能,请确保使用64位O/S和64位版本的java。您可以尝试使用多个并行运行的线程。每个线程在不同的文件上工作,因此它们不会相互干扰。这当然需要更大的内存使用。您可以检查问题是否是单个文件吗?移动System.Out.println()
在处理前输入文件时,应在OOM发生时告知最后一个文件是哪个文件;然后将代码修改为仅在该文件上运行将告知是单个文件问题还是其他问题。强制垃圾收集不太可能影响内存不足异常。垃圾收集将在内存不足之前运行异常被抛出。但是,它并非不可能提供帮助。