netty零拷贝
零拷贝
零拷贝: 是从操作系统层面上讲,即没有CPU的拷贝
传统IO拷贝
传统IO拷贝,即4次拷贝,3次上下文切换:
- 从磁盘拷贝到内核空间(DMA方式)
- 从内核空间拷贝到用户空间(CPU拷贝)
- 从用户空间拷贝到
socket buffer
(CPU拷贝) - 从socket buffer拷贝到
protocol engine
协议栈 (DMA方式)
上下文切换:
- 用户态 -> 内核
- 内核 -> 用户态
- 用户态 -> 内核
DMA
DMA : Direct Memory Access, 直接内存访问
mmap
mmap: 通过内存映射,将文件映射到内核缓冲区,同时,用户空间可以共享内核空间数据
这样 ,在进行网络传输时,就可以减少内核空间到用户空间的拷贝次数
- 从磁盘拷贝到内核空间(DMA方式)
从内核空间拷贝到用户空间(CPU拷贝)- 从内核空间(用户空间)拷贝到
socket buffer
(CPU拷贝) - 从socket buffer拷贝到
protocol engine
协议栈 (DMA方式)
虽然减少了拷贝次数,但上下文切换却没有变,即拷贝次数3次,上下文切换依然是3次
sendFile
sendFile: linux系统函数,数据根本不经过用户态,直接从内核进入到 Socket Buffer,同时,由于和用户态无关,就减少了一次上下文切换
- 从磁盘拷贝到内核空间(DMA方式)
从内核空间拷贝到用户空间(CPU拷贝)从内核空间(用户空间)拷贝到socket buffer
(CPU拷贝)- 从内核空间拷贝到
protocol engine
协议栈 (DMA方式)
即,即拷贝次数2次,上下文切换2次
mmap 和 sendFile的区别
mmap 和 sendFile 的区别:
- mmap 适合小数据量的读写,sendFile 适合大文件传输
- mmap 需要4次上下文切换 ,3次数据拷贝; sendFile 需要3次(linux旧版本)上下文切换,量少2次数据拷贝
- sendFile 可以直接利用 DMA 方式,减少 CPU 拷贝, mmap 则不能(必须从内核拷贝到socket缓冲区)