Java NIO使用零拷贝
Linux的零拷贝确实能够节约一些操作系统的资源。所以Java的NIO为了支持零拷贝,提供了一些类:
在之前的《Java NIO - Buffer》这篇文章里大概介绍了DirectByteBuffer。ByteBuffer主要有两种实现,一种是DirectByteBuffer, 一种是HeapByteBuffer。
其中,DirectByteBuffer直接在堆外分配内存,底层是直接通过JNI调用操作系统的NIO系统调用,所以性能会比较高。而HeapByteBuffer是堆内内存,而且数据需要多一次拷贝,所以性能比较低。
FileChannel
是Java NIO提供的用于复制文件的类,可以把文件复制到磁盘或者网络等。
map
方法其实就是采用了操作系统中的内存映射方式,将内核缓冲区的内存和用户缓冲区的内存做了一个地址映射。
transferTo
方法直接将当前通道内容传输到另一个通道,也就是说这种方式不会有内核缓冲区到用户缓冲区的读写问题。底层是sendfile系统调用。transferFrom
方法同理。
示例代码:
File file = new File("test.txt");RandomAccessFile raf = new RandomAccessFile(file, "rw");FileChannel fileChannel = raf.getChannel();SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("", 8080));// 直接使用了transferTo()进行通道间的数据传输fileChannel.transferTo(0, fileChannel.size(), socketChannel);
作者:公众号_xy的技术圈
链接:www.imooc.com/article/289550
来源:慕课网
以上内容来自幕课网
零拷贝的再次理解零拷贝,是从操作系统的角度来说的。因为内核缓冲区之间,没有数据是重复的(只有 kernel buffer 有一份数据)。
零拷贝不仅仅带来更少的数据复制,还能带来其他的性能优势,例如更少的上下文切换,更少的 CPU 缓存伪共享以及无 CPU 校验和计算。
mmap 适合小数据量读写,sendFile 适合大文件传输。
mmap 需要 4 次上下文切换,3 次数据拷贝;sendFile 需要 3 次上下文切换,最少 2 次数据拷贝。
sendFile 可以利用 DMA 方式,减少 CPU 拷贝,mmap 则不能(必须从内核拷贝到 Socket 缓冲区)。
以上就是了解Linux 和 Java 的零拷贝的详细内容,更多请关注其它相关文章!