如何写入File以避免OutOfMemoryError

时间:2015-12-28 14:15:09

标签: java out-of-memory

以下函数运行到java.lang.OutOfMemoryError,但我增加了项目的内存。 这发生在sb.append(CostMatrix[k][j]);行 我想原因是写入文件效率低下。而不是将所有数据都存储在CostMatrix中,每次更新sb时,最好逐行编写文件。如何实现?

private static void saveDistanceMatricesToCSV(int i, List<Object[]> data)
{
    System.out.println("Saving distance matrix " + i + " to CSV");
    try
    {
        String NEW_LINE = System.getProperty("line.separator");
        File file = new File("clusters/d"+i+".csv");
        FileWriter fw = new FileWriter(file.getAbsoluteFile());
        BufferedWriter bw = new BufferedWriter(fw);
        StringBuilder sb = new StringBuilder();

        int len = data.size();
        double[][] CostMatrix = new double[len][len];
        for (int k=0; k<len; k++)
        {
            for (int j=k; j<len; j++)
            {
                double lat1 = (Float) data.get(k)[3];
                double lon1 = (Float) data.get(k)[4];
                double lat2 = (Float) data.get(j)[3];
                double lon2 = (Float) data.get(j)[4];
                double dist = distfunc(lat1,lon1,lat2,lon2);
                CostMatrix[k][j] = dist;
                CostMatrix[j][k] = dist;
            }           
        }

        for (int k=0; k<len; k++) 
        {
            for (int j=0; j<len; j++)
            {
                sb.append(CostMatrix[k][j]);
                sb.append(",");
            }
            sb.append(NEW_LINE);
        }
        bw.write(sb.toString());
        bw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

3 个答案:

答案 0 :(得分:2)

我看到各种低效率的来源。你正在做两个相同的 周期夫妇:

  • 第一对:迭代数据结构并填充 CostMatrix (顺便在java变量名中以小写字母开头)
  • 第二对:迭代 CostMatrix 以填充 StringBuilder

正如Berger已经告诉你的那样,你可以避免 StringBuilder ,但我也会删除第二个for循环,删除 CostMatrix 的内存使用情况,在第一对周期中直接移动书写结构。

答案 1 :(得分:1)

您可以使用PrintWriter

PrintWriter printWriter = new PrintWriter(file);

然后,不要附加到 StringBuilder ,而只是打印到输出:

printWriter.println(NEW_LINE);

答案 2 :(得分:0)

您可以将每行写入文件,如下所示。

    for (int k = 0; k < len; k++) {
        StringBuilder sb = new StringBuilder();
        for (int j = 0; j < len; j++) {
            sb.append(CostMatrix[k][j]).append(",");
        }
        output.write(sb.toString());
        output.newLine();
    }

BufferWriter的newLine也使用系统属性line.separator。