【Java】NIO零拷贝技术揭秘:CPU不参与的数据传输

在现代操作系统(如 Linux 2.4+ 内核)和现代网卡驱动支持下,FileChannel.transferTo在数据从内核读缓冲区网卡缓冲区 的过程中,使用的是 DMA 拷贝CPU 不参与数据搬运

核心机制:sendfile 与 Scatter/Gather

Java 的FileChannel.transferTo底层在 Linux 上依赖的是sendfile系统调用。为了实现"零拷贝",这里经历了两个阶段的演进:

早期模式

数据从磁盘读取到内核读缓冲区是 DMA 拷贝。然后,CPU 需要将数据从内核读缓冲区拷贝到内核 Socket 缓冲区。最后,再由 DMA 从 Socket 缓冲区拷贝到网卡。

这种模式下,内核读缓冲区到 Socket 缓冲区是 CPU 拷贝。

现代模式:Linux 2.4+ 及之后

这就是现在的标准实现。硬件支持了 Scatter/Gather(分散/聚集) 操作。

  1. DMA 拷贝1:磁盘控制器 -> 内核读缓冲区。CPU 无参与。
  2. CPU 拷贝(仅元数据) :CPU 只是将内核读缓冲区的文件描述符、偏移量、长度 等信息复制到 Socket 缓冲区中。注意:此时并没有复制实际的数据内容。(CPU 开销极小)
  3. DMA 拷贝2:网卡驱动读取 Socket 缓冲区中的描述符,根据描述符直接去内核读缓冲区读取数据,然后发送给网卡。

总共:2 次 DMA 拷贝(数据搬运完全由 DMA 完成),0 次 CPU 数据拷贝,2 次上下文切换。

总结

FileChannel.transferTo的实现中,数据本身从未离开过内核空间,也从未经过 CPU 的寄存器进行搬运。

  • 磁盘到内核读缓冲区:DMA 拷贝。
  • 内核读缓冲区到网卡:DMA 拷贝(依靠 Scatter/Gather 机制,网卡直接来"取"数据)。

这就是为什么它被称为"零拷贝"------指的是 CPU 拷贝次数为零

相关推荐
浮尘笔记1 小时前
Java Snowy框架CI/CD云效自动化部署流程
java·运维·服务器·阿里云·ci/cd·自动化
kkeeper~8 小时前
0基础C语言积跬步之深入理解指针(5下)
c语言·开发语言
一直不明飞行8 小时前
Java的equals(),hashCode()应该在什么时候重写
java·开发语言·jvm
REDcker8 小时前
有限状态机与状态模式详解 FSM建模Java状态模式与C++表驱动模板实践
java·c++·状态模式
盲敲代码的阿豪9 小时前
Python 入门基础教程(爬虫前置版)
开发语言·爬虫·python
你的保护色9 小时前
【无标题】
java·服务器·网络
basketball6169 小时前
C++ 构造函数完全指南:从入门到进阶
java·开发语言·c++
互联科技报9 小时前
2026超融合选型:Top5品牌与市场格局解读
开发语言·perl
weixin199701080169 小时前
[特殊字符] 智能数据采集:数字化转型的“数据石油勘探队”(附Python实战源码)
开发语言·python
淘矿人9 小时前
Claude辅助DevOps实践
java·大数据·运维·人工智能·算法·bug·devops