【发布时间】:2017-08-28 12:31:29
【问题描述】:
我正在开发从文件中读取大量数据的应用程序。基本上,我有一个巨大的文件(大约 1.5 - 2 gigs),其中包含不同的对象(每个文件大约 5 到 1000 万个)。我需要阅读所有这些并将它们放在应用程序中的不同地图上。问题是应用程序在某些时候读取对象时内存不足。只有当我将它设置为使用 -Xmx4096m - 它才能处理文件。但如果文件更大,它将无法再这样做。
这里是sn-p的代码:
String sampleFileName = "sample.file";
FileInputStream fileInputStream = null;
ObjectInputStream objectInputStream = null;
try{
fileInputStream = new FileInputStream(new File(sampleFileName));
int bufferSize = 16 * 1024;
objectInputStream = new ObjectInputStream(new BufferedInputStream(fileInputStream, bufferSize));
while (true){
try{
Object objectToRead = objectInputStream.readUnshared();
if (objectToRead == null){
break;
}
// doing something with the object
}catch (EOFException eofe){
eofe.printStackTrace();
break;
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
} catch (Exception e){
e.printStackTrace();
}finally{
if (objectInputStream != null){
try{
objectInputStream.close();
}catch (Exception e2){
e2.printStackTrace();
}
}
if (fileInputStream != null){
try{
fileInputStream.close();
}catch (Exception e2){
e2.printStackTrace();
}
}
}
首先,我使用的是 objectInputStream.readObject() 而不是 objectInputStream.readUnshared(),所以它部分解决了这个问题。当我将内存从 2048 增加到 4096 时,它开始解析文件。 BufferedInputStream 已在使用中。从网上我只找到了如何读取行或字节的示例,但没有关于对象、性能方面的内容。
如何在不增加 JVM 内存并避免 OutOfMemory 异常的情况下读取文件?有没有办法从文件中读取对象,而不是在内存中保留任何其他内容?
【问题讨论】:
-
物理原理很简单:更大的文件需要更多的内存。那里没有魔法。您的文件不包含对象 - 它们包含映射到映射到对象的字符串的字节。
-
如果您在读取主文件时可以将数据排序到地图中,您可以使用 BufferReader 逐行读取文件,然后使用 PrintWriter 将数据附加到已存在的文件或创建新文件.
-
如果文件太大,别无选择,只能将它们存储在 F.S.阅读:commons.apache.org/proper/commons-jcs
-
(1) 像 h2 这样的嵌入式数据库可能是一个解决方案。也许使用 JPA/OMR 之类的 eclipseLink。与 java 对象一样容易。 (2) 重复的值可以被缓存,所以重复的 String 值会使用同一个 String 对象。
标签: java java-io large-files objectinputstream bufferedinputstream