Java NIO Transfer零拷贝与普通复制测试对比
Transfer API
在 NIO 中,如果其中一个Channel是FileChannel
,则可以利用transferTo()
和transferFrom()
两个API进行高效的数据传输.
其底层原理是利用DMA技术减少内核缓冲区和应用程序缓冲区的数据拷贝来提高效率.
注意这两个API的具体实现是不做完全保证的,也就是说没有规定是否用DMA技术.具体参见API注释.
文件复制的两种方式
public static void copy(File src, File dst) {
try (
FileChannel in = FileChannel.open(src.toPath(), StandardOpenOption.READ);
FileChannel out = FileChannel.open(dst.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE)
) {
in.transferTo(0, in.size(), out);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void oldCopy(File src, File dst) {
try (
BufferedInputStream in = new BufferedInputStream(new FileInputStream(src));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dst))
) {
byte[] data = new byte[1024];
int len = 0;
while ((len = in.read(data)) > 0) {
out.write(data, 0, len);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试结果
机器: WIN10的UBUNTU20虚拟机
运行环境:
$ java -version
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment (build 11.0.7+10-post-Ubuntu-3ubuntu1)
OpenJDK 64-Bit Server VM (build 11.0.7+10-post-Ubuntu-3ubuntu1, mixed mode, sharing)
- Old Copy
$ javac DMAExample.java && java -server -Xms128m -Xmx128m DMAExample 1
true,t1k.txt,70
true,t1M.txt,28
true,t100M.txt,2929
true,t500M.txt,18781
true,t1G.txt,34467
-----------
true,t1k.txt,44
true,t1M.txt,65
true,t100M.txt,4465
true,t500M.txt,17961
true,t1G.txt,33856
- Transfer Copy
$ javac DMAExample.java && java -server -Xms128m -Xmx128m DMAExample 2
false,t1k.txt,72
false,t1M.txt,26
false,t100M.txt,2033
false,t500M.txt,16878
false,t1G.txt,31301
-----------
false,t1k.txt,356
false,t1M.txt,63
false,t100M.txt,3193
false,t500M.txt,11728
false,t1G.txt,22087