0

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

但现在出现了一些要加载的 zip,我想改进它。但我无法让它发挥作用,我得到了 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)

从一开始不到 1 分钟,我在第一个文件中得到了 OutOfMemoryError。

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

我使用 -XX:+HeapDumpOnOutOfMemoryError 运行并使用 Memory Analyser 读取了 .hprof 文件,但这对我没有多大帮助 =/:

内存分析器.png

拜托,我需要帮助。

4

1 回答 1

1

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

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

于 2014-04-16T12:53:14.193 回答