声明:以下内容是基于网络上的公开资料,加上自己的理解整理的。
"零拷贝"(Zero-Copy)是指在数据传输过程中,不需要在用户态和内核态之间进行数据的拷贝操作。传统的数据传输方式涉及到两次数据拷贝,即从应用程序的缓冲区拷贝到内核缓冲区,然后再从内核缓冲区拷贝到目标缓冲区。零拷贝通过避免这两次拷贝操作,提高了数据传输的效率。
零拷贝的实现方式有两种,一种是通过操作系统提供的“内存映射”机制,将用户空间的缓冲区和内核空间的缓冲区映射到同一块物理内存上,这样就避免了数据的实际拷贝;另一种是通过直接IO实现,在直接IO操作中,数据可以从应用程序的缓冲区直接传输到设备,而不需要通过内核的缓冲区。
“程序的缓冲区”是应用程序在用户空间中的内存区域,用于存储即将读取或写入的数据;当应用程序进行 IO 操作时,对于输出操作,数据会首先从程序的缓冲区读取写入到内核缓冲区,对于输入操作,或者从内核缓冲区读取写入到程序的缓冲区。
“内核缓冲区”是操作系统内核中用于缓存数据的区域,当应用程序进行 IO 操作时,数据会在用户空间和内核空间之间进行拷贝。内核缓冲区用于在这两个空间之间传递数据。对于输入操作,数据从程序的缓冲区复制到内核缓冲区。对于输出操作,数据从内核缓冲区复制到程序的缓冲区。
“目标缓冲区”指的是数据将要被传输到的位置,可以是文件、网络连接或其他设备,在数据传输的最终阶段,数据从内核缓冲区传输到目标缓冲区的过程中可能会涉及到多次拷贝,但如果使用零拷贝技术,目标缓冲区和内核缓冲区就可以共享相同的内存,避免实际的数据拷贝。
“零拷贝”避免了多余的数据拷贝操作,减少了CPU和内存的开销,提高了数据传输的效率,降低了传输过程中的延迟,在高性能计算、网络数据传输、文件系统等领域得到了广泛的应用。
Java语言中的 “NIO” 提供了 java.nio
包,包括 java.nio.channels
、java.nio.charset
和 java.nio.file
等子包,用于实现非阻塞的 I/O 操作、字符集处理和文件操作。java.nio.channels
包中的 FileChannel
类可以进行直接 I/O 操作。FileChannel 提供了 transferTo
和 transferFrom
方法,这两个方法可以在文件通道之间直接传输数据,实现零拷贝;使用 DirectByteBuffer 时可以直接分配底层内存,是直接 IO 的一种形式。