title: Nio之零拷贝
date: 2019-06-04 08:36:01
categories:
- Java基础
tags: - nio
Linux中的内核态与用户态
如上图所示,Unix/Linux
的体系架构分为内核空间(kernal space)与用户空间(application space),内核控制着计算机的硬件资源,为上层应用程序提供运行环境。用户空间就是应用程序的活动空间,而内核为应用程序的执行提供着必要的cpu、存储、IO资源等。为了使应用程序访问使用到这些资源,内核就提供了资源访问的接口:系统调用。
传统IO的拷贝
- 数据先从硬件资源被拷贝到内核空间的缓冲区中(
kernel buffer
)。 - 然后再从内核空间的缓冲区中拷贝到用户空间的缓冲区(
application buffer
)中。 - 接着从用户空间再拷贝到内核空间中的
Socket buffer
/Write buffer
中。 - 最后再从
Socket buffer
中拷贝到网卡缓冲区/硬件资源中。
这个过程经过了4次的数据拷贝,其中有2次(1和4)是
DMA
拷贝(直接内存拷贝,不需要cpu
的参与),2和3是cpu
拷贝。
应用程序发起了read
和write
系统调用,会经过4次的上下文切换。
Nio中的零拷贝
sendFile零拷贝
在Java
的Nio
中有个transferTo()
方法,可以将一个channel
里面的字节直接复制到另一个可以写入字节的channel
中,此方法比从通道读取并写入目标通道的简单循环更有效。操作系统可以直接从文件系统缓存向目标通道传输字节,而无需实际复制它们。transferTo()
最后内部封装的是sendFile
这个系统调用。
基本代码如下: