Java中的内存泄漏

时间:2014-04-23 13:32:33

标签: java file-io out-of-memory

这段代码应该打开一个文本文件,跳过第一行,将剩余的行复制到temp变量,清除文件,然后将temp变量重写到文件中。

我怀疑这段代码会产生内存泄漏,尽管我正在清理并关闭所有对象。我在这里错过了什么吗?

这段代码每秒被调用超过30次。

            Scanner scanner_live = new Scanner(file_live);
            ArrayList<String> coll = new ArrayList<String>();
            scanner_live.nextLine();
            while (scanner_live.hasNextLine()) 
                                {
                String line = scanner_live.nextLine();
                coll.add(line);}
            scanner_live.close();

            PrintWriter writer_del = new PrintWriter(file_live);
            writer_del.print("");
            writer_del.close();

            for (String line : coll) {
            FileWriter writer = new FileWriter(file_live.getAbsoluteFile(),true);
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
            bufferedWriter.append(line);
            bufferedWriter.newLine();
            bufferedWriter.close(); 
            writer.close();
                                    }
            coll.clear();

2 个答案:

答案 0 :(得分:3)

我建议你避免存放所有线路。相反,您可以在阅读时复制数据。实际上,您不需要在第一行之后解析每一行,只需要复制其余数据。

try(BufferedReader in = new BufferedReader(new FileReader(file_live);
   BufferedWriter out = new BufferedWriter(new FileWriter(file_live+".tmp"))) {
   // skip the first line
   in.readLine();
   char[] buffer = new char[8*1024];
   for(int len; (len = in.read(buffer)) > 0;)
       out.write(buffer, 0, len);
}
new File(file_live).delete();
new File(file_live+".tmp").renameTo(new File(file_live));
BTW:这种方式一次消耗一行是非常昂贵的,特别是如果文件很大的话。如果可以,我建议不要重写文件,而是分别记录你最喜欢的那条线。

答案 1 :(得分:1)

您的算法但更正确。

    File file = ...
    List<String> lines = new ArrayList<>();
    try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
        // skip first
        String line = reader.readLine();
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    try (PrintWriter writer = new PrintWriter(new FileWriter(file))){
        for (String line : lines) {
            writer.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

如果文件很小,我也不会看到内存泄漏。但是,如果文件很大,那只是因为你将所有行保留在内存中。和JVM内存!=计算机上的所有内存。所以JVM可能会超出限制。