零拷贝 详述
一句话:零拷贝只做一件事——**把数据从“一个地方”搬到“另一个地方”,但**
**1. 不让 CPU 亲自搬运**(省 CPU)
**2. 不让数据绕到用户空间兜一圈**(省内存、省上下文切换)
具体能干的活儿其实就三类,对应三类“地方”:
1. **文件 → Socket**(最典型)
场景:Web 服务器、Kafka Broker、Nginx 把磁盘上的静态文件直接发网卡。
效果:
- 磁盘 → 内核页缓存 → NIC,全程 CPU 只下指令,不搬数据。
- 传统 read+write 要 4 次拷贝、2 次系统调用;sendfile/transferTo 只剩 2 次拷贝、1 次系统调用。
2. **Socket → Socket**(管道转发)
场景:代理、负载均衡、Kafka 跨 Broker 副本同步。
效果:
- NIC → 内核 → NIC,CPU 几乎不碰数据。
- splice/tee 系统调用可做到真正的“零”拷贝,Java 需 JNI。
3. **文件 → 文件**(磁盘克隆)
场景:备份、快照、容器镜像层 dedup。
效果:
- copy_file_range 让内核在同一文件系统内做“引用计数”克隆,不写实际数据块。
一句话总结
**零拷贝不是“加速算法”,而是“省掉不必要的搬运”,最终体现为:更高吞吐、更低 CPU、更低延迟。**