&引用;java.lang.OutOfMemoryError:java堆空间;在xml文件上调用FileUtils.readFileToString时

&引用;java.lang.OutOfMemoryError:java堆空间;在xml文件上调用FileUtils.readFileToString时,java,xml,encoding,heap,fileutils,Java,Xml,Encoding,Heap,Fileutils,我的程序在一个目录上迭代,并使用我的Recoder类中的以下函数,在一个编码上使用FileUtils.readFileToString读取一个文件,并在另一个编码上使用FileUtils.write覆盖它 但是,当它尝试对xml文件执行此操作时,我在标题处遇到异常,否则,它可以正常工作(我已经用.java、.js、.css、.html、.jsp…)在dir上进行了测试 CharsetDetector的内容来自ICU4J,由于某种原因,它在调用cd.detect()时会挂起,因此,现在,我只是将其

我的程序在一个目录上迭代,并使用我的Recoder类中的以下函数,在一个编码上使用
FileUtils.readFileToString
读取一个文件,并在另一个编码上使用
FileUtils.write
覆盖它

但是,当它尝试对xml文件执行此操作时,我在标题处遇到异常,否则,它可以正常工作(我已经用.java、.js、.css、.html、.jsp…)在dir上进行了测试

CharsetDetector的内容来自ICU4J,由于某种原因,它在调用cd.detect()时会挂起,因此,现在,我只是将其保留在注释中

这就是所谓的主要原因:

public static void main( String[] args ){
        DecoderArguments decArgs = new DecoderArguments();
        JCommander jc = new JCommander(decArgs, args);
        try {
            if(args.length>0){
                for(String s : decArgs.files){
                    File file;
                    if (decArgs.recursive){
                        System.out.println("Executando Recursivamente em: "+ s);
                        file = new File(s);
                        if(file.isDirectory()){
                            Collection<File> files = FileUtils.listFiles(file,FileFileFilter.FILE, DirectoryFileFilter.DIRECTORY);
                            for (File f : files){
                                boolean exec=true;
                                for(String excl : decArgs.excludes){
                                    if (f.getAbsolutePath().contains(excl)) exec=false;
                                }
                                if (file.exists() && exec){
                                    if("".equals(decArgs.fromEncoding)){
                                        Recoder.recodeToUTF(f, decArgs.verbose);
                                    }else {
                                        Recoder.recodeFile(f, decArgs.fromEncoding, decArgs.toEncoding, decArgs.verbose);
                                    }
                                    System.gc();
                                }                           
                            }
                        }else{
                            System.out.println("Por favor, informe um diretorio para ler recursivamente.\n"
                                    + "Uso: java -jar decoder.jar <-r> Caminho|Arquivo");
                        }       
                    }else{
                        System.out.println("Convertendo arquivo: "+ s);
                        file = new File(s);
                        boolean exec=true;
                        for(String excl : decArgs.excludes){
                            if (file.getAbsolutePath().contains(excl)) exec=false;
                        }
                        if (file.exists() && exec){
                            if("".equals(decArgs.fromEncoding)){
                                Recoder.recodeToUTF(file, decArgs.verbose);
                            }else {
                                Recoder.recodeFile(file, decArgs.fromEncoding, decArgs.toEncoding, decArgs.verbose);
                            }
                        }
                    }
                }
            }else if (args.length==0){
                System.out.println("Sintaxe incorreta.\n");
                jc.usage();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
publicstaticvoidmain(字符串[]args){
DecoderArguments decArgs=新的DecoderArguments();
JCommander jc=新的JCommander(十格,args);
试一试{
如果(参数长度>0){
用于(字符串s:decArgs.files){
文件;
if(十次递归){
System.out.println(“executanto Recursivamente em:+s”);
文件=新文件;
if(file.isDirectory()){
集合文件=FileUtils.listFiles(文件,filefilter.file,DirectoryFileFilter.DIRECTORY);
用于(文件f:文件){
布尔值exec=true;
for(字符串不包括:decArgs.excludes){
如果(f.getAbsolutePath().contains(exc))exec=false;
}
if(file.exists()&&exec){
如果(“.equals(decArgs.fromEncoding)){
Recoder.recodetoff(f,decArgs.verbose);
}否则{
Recoder.RECODIBLE(f,decArgs.fromEncoding,decArgs.toEncoding,decArgs.verbose);
}
gc();
}                           
}
}否则{
System.out.println(“支持,信息和方向参数递归。\n”
+“Uso:java-jar decoder.jar Caminho | Arquivo”);
}       
}否则{
System.out.println(“Convertendo arquivo:+s”);
文件=新文件;
布尔值exec=true;
for(字符串不包括:decArgs.excludes){
如果(file.getAbsolutePath().contains(exc))exec=false;
}
if(file.exists()&&exec){
如果(“.equals(decArgs.fromEncoding)){
Recoder.recodetoff(文件,decArgs.verbose);
}否则{
Recoder.recondile(文件,decArgs.fromEncoding,decArgs.toEncoding,decArgs.verbose);
}
}
}
}
}else if(args.length==0){
System.out.println(“Sintaxe不正确。\n”);
jc.usage();
}
}捕获(例外e){
e、 printStackTrace();
}
}
注意事项:

  • 我在Eclipse-Xms1024m-Xmx2048m上使用以下VM参数
  • JDK版本1.7.0_75
  • 我尝试了一些System.gc(),但没有效果
  • 它仅在main递归运行时发生(
    decArgs.recursive=true
    ),当
  • 已经在bash上检查了文件编码并对其进行了硬编码以供测试,但也没有运气
你知道为什么会这样吗

提前谢谢

编辑: 使用
Recoder.recodetoff
方法代替
Recoder.recodeFile
不会引发OutOfMemory。可能试图用错误的编码打开会导致内存泄漏


通过分析生成的.hprof,(混乱的)300Mb xml文件使用了大约500Mb的堆。但是,堆的最大大小设置为2Gb,您的内存正在泄漏,因此为了检查问题,您可以 使用以下参数配置JVM
-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=/path/to/dump
。当抛出
OutOfMemoryError
时,将在
/path/to/dump
中创建转储。然后你可以分析它,寻找那些让你记忆模糊的东西。
不错的教程

文件有多大?千字节?兆字节?千兆字节?为什么您需要完整地阅读它们,这似乎非常浪费,您是否可以尝试将它们作为流进行处理(即,读一点,写一点,…)。最后但并非最不重要的一点是:如果您只是“重新编码”一个XML文件而不修复标头,那么很容易导致格式错误:如果标头提到的编码与实际使用的编码不同,则确认XML解析器必须将其报告为错误(如果它能够检测到)。大多数以Kb为单位,一些以Mb为单位,但出于某种原因,有一个300Mb的pom.xml,非常奇怪。我一次阅读整个文件只是为了方便,还没有找到一个可以使用编码的文件流,有什么建议吗?我目前正在替换eclipse上XML文件的编码,但我计划很快将其放入代码中。谢谢
public static void main( String[] args ){
        DecoderArguments decArgs = new DecoderArguments();
        JCommander jc = new JCommander(decArgs, args);
        try {
            if(args.length>0){
                for(String s : decArgs.files){
                    File file;
                    if (decArgs.recursive){
                        System.out.println("Executando Recursivamente em: "+ s);
                        file = new File(s);
                        if(file.isDirectory()){
                            Collection<File> files = FileUtils.listFiles(file,FileFileFilter.FILE, DirectoryFileFilter.DIRECTORY);
                            for (File f : files){
                                boolean exec=true;
                                for(String excl : decArgs.excludes){
                                    if (f.getAbsolutePath().contains(excl)) exec=false;
                                }
                                if (file.exists() && exec){
                                    if("".equals(decArgs.fromEncoding)){
                                        Recoder.recodeToUTF(f, decArgs.verbose);
                                    }else {
                                        Recoder.recodeFile(f, decArgs.fromEncoding, decArgs.toEncoding, decArgs.verbose);
                                    }
                                    System.gc();
                                }                           
                            }
                        }else{
                            System.out.println("Por favor, informe um diretorio para ler recursivamente.\n"
                                    + "Uso: java -jar decoder.jar <-r> Caminho|Arquivo");
                        }       
                    }else{
                        System.out.println("Convertendo arquivo: "+ s);
                        file = new File(s);
                        boolean exec=true;
                        for(String excl : decArgs.excludes){
                            if (file.getAbsolutePath().contains(excl)) exec=false;
                        }
                        if (file.exists() && exec){
                            if("".equals(decArgs.fromEncoding)){
                                Recoder.recodeToUTF(file, decArgs.verbose);
                            }else {
                                Recoder.recodeFile(file, decArgs.fromEncoding, decArgs.toEncoding, decArgs.verbose);
                            }
                        }
                    }
                }
            }else if (args.length==0){
                System.out.println("Sintaxe incorreta.\n");
                jc.usage();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }