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 鏈接更新後附]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章