读取巨大的zip文件时出现“java.lang.OutOfMemoryError:Java堆空间”

时间:2014-04-14 22:39:38

标签: java zip inputstream truevfs

我有一个程序通过namedpipes将数据加载到数据库中,非常酷。 该程序运行了大约2年,并接受文本文件或gzip。

但现在出现了一些拉链加载,我想改进它。但是我无法将其付诸实践,我得到的是OutOfMemoryError。

(当然,我使用-Xms512M -Xmx2048M调用此内容)

以下是我获取InputStream的方法:

PipeLoader.java

protected BufferedReader getBufferedReader(File file, String compression) throws Exception {
    BufferedReader bufferedReader = null;

    if(compression.isEmpty())   {
        bufferedReader = new BufferedReader(new FileReader(file), BUFFER);
    } else if(compression.equalsIgnoreCase("gzip")) {
        InputStream fileStream = new FileInputStream(file);
        InputStream gzipStream = new GZIPInputStream(fileStream);

        // Works fine
        Reader reader = new InputStreamReader(gzipStream);
        bufferedReader = new BufferedReader(reader, BUFFER);
    } else if(compression.equalsIgnoreCase("zip")){
        InputStream fileStream = new FileInputStream(file);
        ZipInputStream zipStream = new ZipInputStream(fileStream);
        zipStream.getNextEntry(); // For testing purposes I'm getting only the first entry

        Reader reader = new InputStreamReader(zipStream); // Works only with small zips
        bufferedReader = new BufferedReader(reader, BUFFER);
    }

    return bufferedReader;
}

我还尝试使用TrueVFS库:

// The same: works with small zip files, OutOfMemoryError with big zip files
TFile tFile = new TFile(file);
TFileInputStream tfis = new TFileInputStream(new TFile(tFile.getAbsolutePath(), tFile.list()[0]));

Reader reader = new InputStreamReader(tfis);
bufferedReader = new BufferedReader(reader, BUFFER);

是的,我正确地关闭了所有东西(请记住,与gz合作!)。

在这种情况下,我需要加载一些zip文件,里面只有1个纯文本文件(~4GB压缩,~35GB解压缩)

我在第一个文件中得到一个OutOfMemoryError,距离开头不到1分钟。

PS:这不是Reading a huge Zip file in java - Out of Memory Error的副本,他可以选择从zip内部读取每个小文件,但我只有一个大文件。

我使用-XX:+ HeapDumpOnOutOfMemoryError运行并使用Memory Analyzer重新启动了.hprof文件,但它对我没什么帮助= /:

MemoryAnalyser.png

拜托,我需要帮助。

1 个答案:

答案 0 :(得分:1)

如果查看堆栈跟踪,可以看到BufferedReader.readLine()最终会导致创建一个非常大的数组,从而导致OutOfMemoryError

由于readLine()一直在读取输入,直到它到达换行符,这表示压缩输入文件中没有(或很少)换行符。