【发布时间】:2012-03-09 03:17:14
【问题描述】:
我有以下一段代码,我正在使用 stringBuffer 对象读取一个大文件,通过创建临时 byte[] 对象执行一些操作,因此,当文件大小很大时,我会遇到内存不足异常说 16 MB。
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:
我对代码进行了以下更改,其中我将整个文件作为 String 加载到内存中,我不创建 byte[] 数组,而是直接从文件中读取并将其直接转换为 arrayList位集。这在我能够处理 20 MB 文件的情况下有所帮助,我想知道是否可以进一步推动这一点以处理最多 30 MB 的文件?
编辑2:
我修改了源代码如下,我删除了我创建的所有冗余数据类型 公共 ArrayList 片段源数据(文件文件名){ 随机存取文件 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;
}
}
【问题讨论】:
-
为什么不创建
BitSets而不是创建byte[]?这将最大限度地减少内存和工作。即,即使您有内存,它也会更快。注意:一台 16 GB 的 PC 只需 1000 美元,所以也许是时候获得更多内存了。 ;)
标签: java exception heap-memory