我有一个程序通过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文件,但它对我没什么帮助= /:
拜托,我需要帮助。
答案 0 :(得分:1)
如果查看堆栈跟踪,可以看到BufferedReader.readLine()
最终会导致创建一个非常大的数组,从而导致OutOfMemoryError
。
由于readLine()
一直在读取输入,直到它到达换行符,这表示压缩输入文件中没有(或很少)换行符。