Java零拷貝問題

概述

零複製(英語:zero-copy;也叫做零拷貝)技術是指計算機執行操作時,cpu不需要先將數據從某處內存複製到另外一個特定區域。這種技術通常通過網絡傳輸文件時節省CPU週期和帶寬。

傳統IO傳輸模型

傳統io介紹圖

傳統IO分析

在Java當中IO存在這三個對象,一個是user space用戶空間,一個是kernel space內核空間,還有一個是hardware磁盤對象

  • jvm發起了一次讀取事件時,首先會通過內核空間對磁盤進行一次DAM的IO操作,將磁盤中的數據寫入到內核空間當中。
  • 再將內核空間中的數據進行一次拷貝,將數據拷貝到用戶空間當中
  • jvm發起一次寫入事件時,先將用戶空間中的數據拷貝到內核空間中
  • 再通過內核空間將數據寫入到磁盤中

這種拷貝我們進行了四次拷貝四次上下文切換,這種拷貝和上下文切換極大的消耗時間和性能

網絡IO改進版本

零拷貝IO階段1
其實這種模型他也是一種零拷貝,但是它在內核當中多做了一步拷貝過程,將內核空間中的數據拷貝到了socket buffer當中,這是這個模型的一個大缺陷。

它總共進行了兩次上下文的切換,和三次拷貝過程

真正的零拷貝

真正的零拷貝內容

  • JVM發起讀取文件請求時,將文件操作完全交給了系統內核來操作
  • 通過DMA拷貝將數據讀取到內核空間當中,再將內核當中的數據頭信息(比如:文件名稱,文件長度等信息拷貝到socket Buffer中 當然這個過程時間我們可以忽略不記)再將kemel buffer中的數據通過文件引擎,配合socket buffer中的信息一起寫入到文件磁盤當中。
  • 當然這種拷貝需要系統支持scatter-and-gather

Java NIO中實現零拷貝的幾種方式

DirectByteBuffer

在調用ByteBuffer.allocateDirect()方法獲得。JVM將使用malloc()方法在堆內存之外分配內存空間。因爲它不是由JVM管理,所以你的內存空間是頁面對其的,不受GC影響 ,這使得它成爲處理本地代碼的完美選擇。然而你需要像C程序員一樣,自己管理內存。

MappedByteBuffer

零拷貝是操作系統底層的一種實現,我們在網絡編程中,利用操作系統這一特性,可以大大提高數據傳輸的效率。這也是目前網絡編程框架中都會採用的方式,理解好零拷貝,有助於我們進一步學習Netty等網絡通信框架的底層原理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章