零拷贝:从操作系统角度说是没有cpu拷贝。
零拷贝不仅带来更少的数据复制,还带来其他的性能优势,例如更少的上下文切换,更少的cpu缓存伪共享以及无cpu校验和计算。
java程序中,常用的零拷贝是:内存映射(mmap)和sendFile
NIO零拷贝使用方式:transferTo
先看下传统的IO数据读写代码如下:
传统IO模型:
注:DMA(direct memory access)直接内存拷贝不使用CPU
一、mmap优化
mmap通过内存映射,将文件映射到内核缓冲区,同时用户空间可以共享内核空间的数据。在进行网络传输的时候,减少内核空间到用户空间的拷贝次数。
二、sendFile优化
linux2.1版本提供了sendFile函数,数据根本不经过用户态,直接从内核态缓冲区进入到socket buffer,同时由于和用户态完全无关,就减少了一次上下文切换。
linux2.4做了进一步优化,避免从内核缓冲区拷贝到socket buffer的操作,直接拷贝到协议栈,从而再一次减少数据拷贝。
三、mmap和sendFile的对比
1、mmap适合小数据量的读写,sendFile适合大文件的传输
2、mmap需要4次上下文切换,3次数据拷贝;sendFile需要3次上下文切换,最少2次数据拷贝
3、sendFile可以使用DMA方式,减少cpu拷贝。mmap则不能