java使用映射文件ByteBufferMap来复制一个文件内存溢出
下面的程序是使用映射文件ByteBufferMap来复制一个文件,每次复制到大概7,8百M的时候就出内存溢出异常
大家看看是什么原因啊?我的电脑内存是2G,每次映射文件的大小是128M
复制的文件大小是1.3G
Java code? java.io.IOException: Map failed at sun.nio.ch.FileChannelImpl.map(Unknown Source) at iotest.ByteBufferMap.main(ByteBufferMap.java:38) Caused by: java.lang.OutOfMemoryError: Map failed at sun.nio.ch.FileChannelImpl.map0(Native Method) ... 2 more
Java code? import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.IntBuffer; import java.nio.channels.FileChannel; public class ByteBufferMap { public static void main(String[] args) { FileChannel fcIn = null; FileChannel fcOut = null; try { String filePath = "F:\\Anime\\Gundam00\\S2\\25.mkv";//1.3G fcIn = new FileInputStream(new File(filePath)).getChannel(); fcOut = new RandomAccessFile(new File("G:\\1.mkv"), "rw").getChannel(); IntBuffer bufOut; IntBuffer bufIn; long readSize = 128 * 1024 * 1024;//每次映射的大小 long s;//映射开始处 long e;//映射结束处 int i = 0; long allSize = fcIn.size();//文件的大小 long start = System.currentTimeMillis(); do { s = i++ * readSize; e = s + readSize > allSize ? s + allSize % readSize : s + readSize; bufIn = fcIn.map(FileChannel.MapMode.READ_ONLY, s, e).asIntBuffer(); bufOut = fcOut.map(FileChannel.MapMode.READ_WRITE, s, e).asIntBuffer(); while(bufIn.hasRemaining()) { bufOut.put(bufIn.get()); } } while(e < allSize); long end = System.currentTimeMillis(); System.out.println("Time:" + ((double) ((end - start) / 1000)) + "s"); } catch(IOException e) { e.printStackTrace(); } finally { try { fcIn.close(); fcOut.close(); } catch (IOException e) { e.printStackTrace(); } } } }
把map的第三个参数理解错了
package iotest; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.IntBuffer; import java.nio.channels.FileChannel; public class ByteBufferMap { public static void main(String[] args) { FileChannel fcIn = null; FileChannel fcOut = null; try { String filePath = "F:\\Anime\\Gundam00\\S2\\25.mkv"; fcIn = new FileInputStream(new File(filePath)).getChannel(); fcOut = new RandomAccessFile(new File("G:\\1.mkv"), "rw").getChannel(); IntBuffer bufOut; IntBuffer bufIn; int readSize = 256 * 1024 * 1024;//每次映射的大小 long s;//映射开始处 long e;//映射结束处 int i = 0; long allSize = fcIn.size(); System.out.println(Integer.MAX_VALUE + " " + readSize); long start = System.currentTimeMillis(); do { s = i++ * readSize; e = s + readSize > allSize ? allSize % readSize : readSize; /*System.out.println(s); System.out.println(e); System.out.println(allSize + "\n");*/ bufIn = fcIn.map(FileChannel.MapMode.READ_ONLY, s, e).asIntBuffer(); bufOut = fcOut.map(FileChannel.MapMode.READ_WRITE, s, e).asIntBuffer(); while(bufIn.hasRemaining()) { bufOut.put(bufIn.get()); } } while(s + e < allSize); long end = System.currentTimeMillis(); System.out.println("Time:" + ((double) ((end - start) / 1000)) + "s"); } catch(IOException e) { e.printStackTrace(); } finally { try { fcIn.close(); fcOut.close(); } catch (IOException e) { e.printStackTrace(); } } } }