Netty由浅到深_第三章_ NIO与零拷贝

  1. 在java程序中,常用的零拷贝有mmap(内存映射)和sendFile。先看一下java传统IO和网络编程的一段代码
    在这里插入图片描述

    上述代码:
    1) 首先先把Hard Driver(硬件)数据进行DMA(direct memory acces 直接内存拷贝,不使用CPU)copy 到 kernel Buffer(内核缓冲区中)
    2) 接下来从kernel Buffer 通过 CPU copyuser Buffer
    3) 此时用户进行一些操作后通过 CPU copysocket buffer
    4) 然后再通过DMA copy protocol engine(协议栈)。总结一下,经行了4次拷贝,3上下文切换
    在这里插入图片描述

  2. 所以出现mmap,即内存映射优化技术。将文件映射到内核缓存区,同时,用户空间可以共享内核空间的数据,这样,在进行网络传输时,可以减少内核空间到用户空间的拷贝次数。即减少了上述步骤2。总结一下,经行了3次拷贝,3次上下文切换。
    在这里插入图片描述

  3. 于是又出现sendFile。Linux2.1版本提供了sendFile函数,其基本原理:数据根本不经过用户态,直接从内核进入到socket Buffer,同时,由于和用户态无关,就减少了一次上下文切换。即减少了上述步骤2和3。总结一下,经行了3次拷贝,2次状态切换
    在这里插入图片描述

  4. sendFile优化,在linux的2.4版本中,做了一些修改,避免了从内核缓冲区拷贝到socketBuffer的操作直接拷贝到协议栈,从而在减少了数据库拷贝。但是还是有少部分数据要经过一次CPU拷贝,kernel buffer->socketBuffer,如数据长度,偏移量。X消耗低,可以忽略不记
    所以总共经过2次拷贝,2次上下文切换(这就是零拷贝)

在这里插入图片描述
5. 我们说的零拷贝,是从操作系统角度来说的,因为内核缓冲区之间,没有数据是重复的(只有kernel buffer有一份数据)
6. NIO实现零拷贝调用transferto()方法
在linux下,一次调用transferto()方法可以完成传输
在window下,调用一次transferto()方法只能发送8M数据,就需要分段传输文件

[前面补充这么多io知识,就是为大家学习Netty打基础 下一章更新Netty 链接更新后附]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章