我有下面的代码,我使用 stringBuffer 对象读取大文件,通过创建临时 byte[] 对象执行一些操作,因此,当文件大小很大时,我会遇到内存不足异常比如说16MB。
StringBuffer dataBuffer;
ArrayList<byte[]> sourceFragments;
ArrayList<BitSet> sourceBits = new ArrayList<BitSet>();
dataBuffer = eHelper.readFile(encoder.getFileName());
sourceFragments = eHelper.fragmentFile(dataBuffer.toString());
/*
* converting byte[] to BitSet
the below loop is run 128 times
*/
Iterator<byte[]> iter = sourceFragments.iterator();
while (iter.hasNext()) {
byte[] temp = iter.next();
// temp.length will return 128 KB
sourceBits.add(eHelper.byteArrayToBitSet(temp));
}
我想知道是否有办法防止这种内存不足异常的发生。我没有考虑增加堆空间的选项,我在 32 位机器上使用默认堆空间。有什么方法可以减少正在创建的临时对象的数量,以便避免 outOfMemory 异常
编辑1:
我对代码进行了以下更改,我不将整个文件作为字符串加载到内存中,我不创建 byte[] 数组,而是直接从文件读取并将其直接转换为 arrayList位集。这对我能够处理 20 MB 文件有所帮助,我想知道是否可以进一步插入这一点以处理最大 30 MB 文件?
编辑2:
我修改了源代码如下,我删除了我创建的所有冗余数据类型 公共(public)ArrayListfragmentSourceData(文件文件名){ 随机访问文件 r ; ArrayList sourceBits = new ArrayList();
try {
r= new RandomAccessFile(filename, "r");
System.out.println(r.length());
encoder.setSourceFileLength((int)r.length());
int fragmentSize = encoder.calculateFragmentSize();
System.out.println(fragmentSize);
encoder.setFragmentSize(fragmentSize);
encoder.setParameters();
byte[] b = new byte[fragmentSize] ;
long new_pos=0;
int i=0;
while(new_pos<=encoder.getSourceFileLength()){
i++;
r.read(b ,0, fragmentSize );
new_pos=fragmentSize*i;
r.seek(new_pos);
sourceBits.add(BitSet.valueOf(b));
}
r.close();
b=null;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sourceBits;
}
}
最佳答案
似乎很明显,但是为什么要将整个文件读入内存?为什么不一次读取 128KB?
fragmentFile
的作用也不明显。它如何将字符串转换为byte[]
片段?
关于java - 改进java代码以避免堆内存不足异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9333064/