零拷贝

返回 面试

「零拷贝」指减少数据在用户态与内核态之间无意义的 CPU 拷贝和上下文切换。详解 零拷贝


传统 IO 问题(读文件发网络)

File.read(buf);      // 磁盘 → 内核 → 用户
Socket.write(buf);   // 用户 → 内核 → 网卡

4 次拷贝(2 次 DMA + 2 次 CPU)+ 4 次上下文切换

数据只是原样转发,却在用户空间「转了一圈」——②③ 两次 CPU 拷贝可省。


三种优化方案

方案CPU 拷贝数据进用户空间Java API场景
传统 read/write2 次InputStream需在应用层处理内容
mmap + write1 次映射访问MappedByteBuffer大文件随机读写
sendfile1 次FileChannel.transferTo()静态文件、Kafka
sendfile + SG-DMA0 次transferTo(硬件支持)Nginx、Kafka

sendfile 流程

磁盘 ──DMA──► page cache ──CPU──► socket buffer ──DMA──► 网卡
              (数据不进入 JVM 堆)
fileChannel.transferTo(0, size, socketChannel);

限制:应用读不到字节内容,无法在同一链路里加密/改内容(需先处理再普通 write)。


谁在用

组件用途
KafkaBroker 把日志 sendfile 给消费者
Nginxsendfile on; 静态资源
NettyFileRegion 封装 transferTo

epoll 多路复用 配合:epoll 决定「何时发」;零拷贝决定「怎么发」——见 零拷贝 ≠ 非阻塞


易混淆点

概念说明
零拷贝减少内核/用户态间 CPU 拷贝
DirectByteBuffer堆外内存,减少 JVM 堆 ↔ 内核 拷贝;仍是另一维度
Netty CompositeByteBuf逻辑合并缓冲区,避免合并时拷贝(用户态优化)

常见面试题

Q:零拷贝是 0 次拷贝吗?
A:通常指 0 次 CPU 拷贝;DMA 拷贝仍存在。SG-DMA 下可连 CPU 拷贝也去掉。

Q:为什么 Kafka 快?和零拷贝关系?
A:顺序写 + Page Cache + sendfile 消费 + 批量 + 分区;零拷贝是其中之一。见 Kafka常见面试题

Q:什么场景不能用零拷贝?
A:需要在应用层解析、加密、压缩、修改数据时,必须进用户缓冲区。

Q:mmap 和 sendfile 区别?
A:mmap 数据映射到用户空间可读;sendfile 数据不进用户空间,适合纯转发。


相关笔记