合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
  ### 5.1 零拷贝 零拷贝指的是数据不会重复拷贝到JVM内存当中,用户态和内核态之间没有拷贝操作,数据直接由内核缓冲区拷贝到另外的IO缓冲区(例如网卡的Socket缓冲区)。 以一般的Socket读写操作为例:将一个本地文件通过IO读出并写到网卡中。 ~~~java File f = new File("helloword/data.txt"); RandomAccessFile file = new RandomAccessFile(file, "r"); byte[] buf = new byte[(int)f.length()]; file.read(buf); Socket socket = ...; socket.getOutputStream().write(buf); ~~~ :-: ![](https://img.kancloud.cn/94/81/948100e00835ab21cb9aaf7ccf3f0604_492x263.png) * Java本身并不具备IO读写的能力(所有的应用程序都是),对于IO读写的操作,要去调用操作系统提供的相关系统调用函数,通过系统调用会将进程从用户态切换到内核态(int 0x80)。 * 接着操作系统会通过DMA的方式进行IO的读写操作`拷贝(1)`,这个时候不用CPU参与,但是相对应的用户线程要被阻塞。 * 操作系统将数据从IO设备中读取出来之后存放到内核缓冲区中,接在再`拷贝(2)`到用户缓冲区中,这个过程从内核态转换到用户态。 * 用户缓冲区在处理数据之后调用writer方法将输入写入内核缓冲区(Socket缓冲区)(`拷贝(3)`),这个过程也要发生一次用户态到内核态的转换。 * 接着操作系统再使用DMA的方式将Socket缓冲区的内容写入到网卡中。(`拷贝4`) 可以发现:这个过程发生了3次用户态和内核态的切换,4次数据拷贝。 而在使用了直接内存之后就可以对数据的拷贝过程进行优化: