前言
零拷贝
是老生常谈的话题了, 不管是Kafka
还是Netty
都用到了零拷贝的知识, 本篇着重讲解了什么是零拷贝, 同时在Java
和Netty
中分别是怎么实现零拷贝的
什么是零拷贝
零拷贝是指计算机在执行IO操作的时候, CPU不需要将数据从一个存储区复制到另一个存储区, 进而减少上下文切换以及 CPU 拷贝的时间, 这是一种IO操作优化技术
零拷贝不是没有拷贝数据, 而是减少用户态, 内核态的切换次数 和 CPU拷贝次数
, 目前实现零拷贝的主要三种方式分别是:
- mmap + write
- sendfile
- 带有DMA收集拷贝功能的 sendfile
mmap
虚拟内存把内核空间和用户空间的虚拟地址映射到同一个物理地址, 从而减少数据拷贝次数, mmap
技术就是利用了虚拟内存的这个特点, 它将内核中的读缓冲区与用户空间的缓冲区进行映射, 所有的IO操作都在内核中完成
sendfile
sendfile
是Linux 2.1
版本之后内核引入的一个系统调用函数
sendfile
表示在两个文件描述符之间传输数据, 他是在操作系统内核中完成的, 避免了数据从内核缓冲区和用户缓冲区之间的拷贝操作, 因此可以用其来实现零拷贝
在Linux 2.4
版本之后, 对sendfile
进行了升级, 引入了SG-DMA
技术, 可以直接从缓冲区中将数据读取到网卡, 这样的话可以省去CPU拷贝
Java 实现的零拷贝
mmap
在Java NIO
有一个ByteBuffer
的子