我正在使用带有合并的外部排序来对整数文件进行排序。通常对此的解决方案是使用 -Xmx 增加 JVM 的堆大小,但我想知道是否有一种方法可以在不增加堆大小的情况下改进我的代码。抛出错误的方法是合并方法。public static void merge(RandomAccessFile a1, RandomAccessFile a2, RandomAccessFile b1,DataOutputStream output, int start, int end) throws FileNotFoundException, IOException { //a1: file being read from //b1: file being written to if((int)a1.length() == 0) { return; } DataInputStream input_a1 = new DataInputStream( new BufferedInputStream(new FileInputStream(a1.getFD()))); DataInputStream input_a2 = new DataInputStream( new BufferedInputStream(new FileInputStream(a2.getFD()))); b1.seek(start); //set output pointer to start int mid = (start + end) /2; int file_length = (int)a1.length(); //basically if second block is empty so just copy if (end > file_length) { end = file_length; if (end <= mid) { //copy from start to EOF int no_of_ints_left = (file_length - start)/4; for(int i = 1; i <= no_of_ints_left; i++) { output.writeInt(input_a1.readInt()); } output.flush(); return; } } int first_counter = start; int second_counter = mid; int x; int y; while(first_counter < mid && second_counter < end) { input_a1.mark(first_counter); input_a2.mark(second_counter); x = input_a1.readInt(); y = input_a2.readInt(); if(x < y) { output.writeInt(x); input_a2.reset(); first_counter += 4; } else { output.writeInt(y); input_a1.reset(); second_counter += 4; } }导致 OutOfMemory 错误的行是 x = input_a1.readInt() 行,但我怀疑这是错误的原因。我尝试在每次调用 merge() 后调用 System.gc(),但这并没有解决问题。我还有哪些其他方法可以优化该方法以减少内存使用量?
1 回答
ABOUTYOU
TA贡献1812条经验 获得超5个赞
mark
用于缓冲流的代码。这将需要整个标记部分都在内存中,这可能是您的问题。
RandomAccessFile
可能是获得相同功能但将数据保留在磁盘上的最简单方法。内存映射java.nio
是一种更复杂的技术 - 在 32 位机器上仍然会遇到问题。但是,我猜您仍然可能会遇到大文件的严重性能问题。
(堆栈跟踪对于准确查看分配失败的内容很有用。可能重新分配缓冲区。尽管分析堆会告诉您实际占用内存的内容。)
添加回答
举报
0/150
提交
取消