Linux傳統IO
Linux傳統IO
Linux傳統上的資料。現在要把我從磁碟發到網卡,需要經過以下步驟:
#如上圖:作業系統把記憶體分為了核心空間和使用者空間。首先位於使用者空間的應用程式使用發起資料讀取操作,例如JVM發起read()系統呼叫。這時候作業系統會進行一次
上下文切換:從使用者空間切換到核心空間。最後進行上下文切換,再換回使用者空間的上下文。然後核心空間通知磁碟,核心把我從磁碟copy到核心緩衝區。這個過程是由一個叫做「DMA(Direct memory access)」的硬體來做的,所以不需要CPU的參與。
然後核心把我從核心緩衝區copy到應用程式緩衝區,這裡需要CPU的參與。
整個讀取操作的過程需要兩次上下文切換和兩次copy
。相關學習推薦:Java影片教學
寫操作
#寫操作與讀取操作類似,只是方向相反而已,仍然需要兩次上下文切換和兩次資料的copy。我可能會被寫到磁碟,也可能會被寫到網卡。
記憶體映射
現在主流的作業系統都使用了虛擬記憶體
。簡單來說,就是用虛擬位址取代實體位址
,這樣做可以讓多個虛擬記憶體只想同一個實體位址,虛擬記憶體的空間可以遠大於實體記憶體的空間。- 那如果作業系統能夠把使用者空間的應用程式緩衝區和核心空間的核心緩衝區映射到同一個實體位址,那豈不是就少了很多複製的過程?如下圖:
Linux零拷貝
所以為了解決這個問題,聰明的Linux開發者們寫了一些新的系統呼叫來做這個事。主要有兩種方式:mmap write
mmap write
mmap()
使用戶緩衝區和核心讀取緩衝區的記憶體位址為同一記憶體位址,也就是說,不需要CPU再將我從核心讀取緩衝區複製到用戶緩衝區啦!
當使用write()
系統呼叫的時候,CPU將我從核心緩衝區(等同於使用者緩衝區)直接寫入到需要傳送的核心緩衝區,例如網路發送緩衝區(socket buffer)
,然後透過DMA的方式將我傳入到網卡驅動程式(或磁碟)中準備發送。 ###############mmap write的方式讀寫資料總共需要兩次系統調用,4次上下文切換,2次DMA Copy和1次CPU Copy。 ############sendfile######sendfile也是一個系統調用,它其實本質上就是把上述兩個系統調用的函數合起來,變成了一個調用。這樣做的好處是,作業系統只需要2次上下文切換了,減少了2次上下文切換的開銷。 ###了解Linux 和 Java 的零拷貝
Linux2.4核心對sendfile進行了優化,提供了了解Linux 和 Java 的零拷貝操作,這個操作可以把上圖中的最後一次CPU copy去掉,原理就是不複製數據,而是把資料在之前的核心緩衝區(比如圖中的案例是Read Buffer)的記憶體位址、偏移記錄傳送給目標核心緩衝區(比如圖中案例的Socket Buffer),這樣在最後的DMA copy階段就可以拿著這個指標直接去找資料copy了。
Java NIO使用零拷貝
Linux的零拷貝確實能夠節省一些作業系統的資源。所以Java的NIO為了支援零拷貝,提供了一些類別:
- DirectByteBuffer
- FileChannel
在之前的《Java NIO - Buffer》這篇文章裡大概介紹了DirectByteBuffer。 ByteBuffer主要有兩種實現,一種是DirectByteBuffer, 一種是HeapByteBuffer。
其中,DirectByteBuffer直接在堆外分配內存,底層是直接透過JNI調用作業系統的NIO系統調用,所以效能會比較高。而HeapByteBuffer是堆內內存,而且資料需要多一次拷貝,所以效能比較低。
FileChannel
是Java NIO提供的複製檔案的類,可以把檔案複製到磁碟或網路等。
map
方法其實就是採用了作業系統中的記憶體映射方式,將核心緩衝區的記憶體和使用者緩衝區的記憶體做了一個位址映射。
transferTo
方法直接將目前頻道內容傳送到另一個頻道,也就是說這種方式不會有核心緩衝區到使用者緩衝區的讀寫問題。底層是sendfile系統呼叫。 transferFrom
方法同理。
範例程式碼:
File file = new File("test.txt");RandomAccessFile raf = new RandomAccessFile(file, "rw");FileChannel fileChannel = raf.getChannel();SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("", 8080));// 直接使用了transferTo()进行通道间的数据传输fileChannel.transferTo(0, fileChannel.size(), socketChannel);
作者:公眾號_xy的技術圈
#連結:www.imooc.com/article/289550
#來源:慕課網
以上內容來自幕課網
零拷貝的再次理解
零拷貝,是從操作系統的角度來說的。因為內核緩衝區之間,沒有資料是重複的(只有 kernel buffer 有一份資料)。
零拷貝不僅帶來更少的資料複製,還能帶來其他的效能優勢,例如更少的上下文切換,更少的CPU 快取偽共享以及無CPU校驗和計算。
mmap和sendFile的差異
#mmap 適合小資料量讀寫,sendFile 適合大檔案傳輸。
mmap 需要 4 次上下文切換,3 次資料拷貝;sendFile 需要 3 次上下文切換,最少 2 次資料拷貝。
sendFile 可以利用 DMA 方式,減少 CPU 拷貝,mmap 則不能(必須從核心拷貝到 Socket 緩衝區)。
以上是了解Linux 和 Java 的零拷貝的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

Dreamweaver CS6
視覺化網頁開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),