本博文主要討論I/O在底層是如何工作的。本文服務(wù)的讀者,迫切希望了解Java I/O操作是在機器層面如何進(jìn)行映射,以及應用運行時(shí)硬件都做了什么。假定你熟悉基本的I/O操作,比如通過(guò)Java I/O API讀寫(xiě)文件。這些內容不在本文的討論范圍。
緩沖與緩沖的處理方式,是所有I/O操作的基礎。術(shù)語(yǔ)“輸入、輸出”只對數據移入和移出緩存有意義。任何時(shí)候都要把它記在心中。通常,進(jìn)程執行操作系統的I/O請求包括數據從緩沖區排出(寫(xiě)操作)和數據填充緩沖區(讀操作)。這就是I/O的整體概念。在操作系統內部執行這些傳輸操作的機制可以非常復雜,但從概念上講非常簡(jiǎn)單。我們將在文中用一小部分來(lái)討論它。
上圖顯示了一個(gè)簡(jiǎn)化的“邏輯”圖,它表示塊數據如何從外部源,例如一個(gè)磁盤(pán),移動(dòng)到進(jìn)程的存儲區域(例如RAM)中。首先,進(jìn)程要求其緩沖通過(guò)read()系統調用填滿(mǎn)。這個(gè)系統調用導致內核向磁盤(pán)控 制硬件發(fā)出一條命令要從磁盤(pán)獲取數據。磁盤(pán)控制器通過(guò)DMA直接將數據寫(xiě)入內核的內存緩沖區,不需要主CPU進(jìn)一步幫助。當請求read()操作時(shí),一旦磁盤(pán)控制器完成了緩存的填 寫(xiě),內核從內核空間的臨時(shí)緩存拷貝數據到進(jìn)程指定的緩存中。
有一點(diǎn)需要注意,在內核試圖緩存及預取數據時(shí),內核空間中進(jìn)程請求的數據可能已經(jīng)就緒了。如果這樣,進(jìn)程請求的數據會(huì )被拷貝出來(lái)。如果數據不可用,則進(jìn)程被掛起。內核將把數據讀入內存。
你可能已經(jīng)多次聽(tīng)說(shuō)過(guò)虛擬內存了。讓我再介紹一下。
所有現代操作系統都使用虛擬內存。虛擬內存意味著(zhù)人工或者虛擬地址代替物理(硬件RAM)內存地址。虛擬地址有兩個(gè)重要優(yōu)勢:
多個(gè)虛擬地址可以映射到相同的物理地址。一個(gè)虛擬地址空間可以大于實(shí)際可用硬件內存。在上面介紹中,從內核空間拷貝到最終用戶(hù)緩存看起來(lái)增加了額外的工作。為什么不告訴磁盤(pán)控制器直接發(fā)送數據到用戶(hù)空間的緩存呢?好吧,這是由虛擬內存實(shí)現的。用到了上面的優(yōu)勢1。
通過(guò)將內核空間地址映射到相同的物理地址作為一個(gè)用戶(hù)空間的虛擬地址,DMA硬件(只能訪(fǎng)問(wèn)物理內存地址)可以填充緩存。這個(gè)緩存同時(shí)對內核和用戶(hù)空間進(jìn)程可見(jiàn)。
這就消除了內核和用戶(hù)空間之間的拷貝,但是需要內核和用戶(hù)緩沖區使用相同的頁(yè)面對齊方式。緩沖區必須使用的塊大小的倍數磁盤(pán)控制器(通常是512字節的磁盤(pán)扇區)。操作系統將其內存地址空間劃分為頁(yè)面,這是固定大小的字節組。這些內存頁(yè)總是磁盤(pán)塊大小的倍數和通常為2倍(簡(jiǎn)化尋址)。典型的內存頁(yè)面大小是1024、2048和4096字節。虛擬和物理內存頁(yè)面大小總是相同的。
為了支持虛擬內存的第2個(gè)優(yōu)勢(擁有大于物理內 存的可尋址空間)需要進(jìn)行虛擬內存分頁(yè)(通常稱(chēng)為頁(yè)交換)。這種機制憑借虛擬內存空間的頁(yè)可以持久保存在外部磁盤(pán)存儲,從而為其他虛擬頁(yè)放入物理內存提供了空間。本質(zhì)上講,物理內存擔當了分頁(yè)區域的緩存。分頁(yè)區是磁盤(pán)上的空間,內存頁(yè)的內容被強迫交換出物理內存時(shí)會(huì )保存到這里。
調整內存頁(yè)面大小為磁盤(pán)塊大小的倍數,讓內核可以直接發(fā)送指令到磁盤(pán)控制器硬件,將內存頁(yè)寫(xiě)到磁盤(pán)或者在需要時(shí)重新加載。事實(shí)證明,所有的磁盤(pán)I/O操作都是在頁(yè)面級別上完成的。這是數據在現代分頁(yè)操作系統上在磁盤(pán)與物理內存之間移動(dòng)的唯一方式。
現代CPU包含一個(gè)名為內存管理單元(MMU)的子系統。這 個(gè)設備邏輯上位于CPU與物理內存之間。它包含從虛擬地址向物理內存地址轉化的映射信息。當CPU引用一個(gè)內存位置時(shí),MMU決定哪些頁(yè)需要駐留(通常通過(guò)移位或屏蔽地址的某些位)以及轉化虛擬頁(yè)號到物理頁(yè)號(由硬件實(shí)現,速度奇快)。
文件I/O總是發(fā)生在文件系統的上下文切換中。文件系統跟磁盤(pán)是完全不同的事物。磁盤(pán)按段存儲數據,每段512字節。它是硬件設備,對保存的文件語(yǔ)義一無(wú)所知。它們只是提供了一定數量的可以保存數據的插槽。從這方面來(lái)說(shuō),一個(gè)磁盤(pán)的段與 內存分頁(yè)類(lèi)似。它們都有統一的大小并且是個(gè)可尋址的大數組。
另一方面,文件系統是更高層抽象。文件系統是安排和翻譯保存磁盤(pán)(或其它可隨機訪(fǎng)問(wèn),面向塊的設備)數據的一種特殊方法。你寫(xiě)的代碼幾乎總是與文件系統交互,而不與磁盤(pán)直接交互。文件系統定義了文件名、路徑、文件、文件屬性等抽象。
一個(gè)文件系統組織(在硬盤(pán)中)了一系列均勻大小的數據塊。有些塊保存元信息,如空閑塊的映射、目錄、索引等。其它塊包含實(shí)際的文件數據。單個(gè)文件的元信息描述哪些塊包含文件數據、數據結束位置、最后更新時(shí)間等。當用戶(hù)進(jìn)程發(fā)送請求來(lái)讀取文件數據時(shí),文件系統實(shí)現準確定位數據在磁盤(pán)上的位置。然后采取行動(dòng)將這些磁盤(pán)扇區放入內存中。
文件系統也有頁(yè)的概念,它的大小可能與一個(gè)基本內存頁(yè)面大小相同或者是它的倍數。典型的文件系統頁(yè)面大小范圍從2048到8192字節,并且總是一個(gè)基本內存頁(yè)面大小的倍數。
分頁(yè)文件系統執行I/O可以歸結為以下邏輯步驟:
確定請求跨越了哪些文件系統分頁(yè)(磁盤(pán)段的集合)。磁盤(pán)上的文件內容及元數據可能分布在多個(gè)文件系統頁(yè)面上,這些頁(yè)面可能是不連續的。分配足夠多的內核空間內存頁(yè)面來(lái)保存相同的文件系統頁(yè)面。建立這些內存分頁(yè)與磁盤(pán)上文件系統分頁(yè)的映射。對每一個(gè)內存分頁(yè)產(chǎn)生分頁(yè)錯誤。虛擬內存系統陷入分頁(yè)錯誤并且調度pagins(頁(yè)面調入),通過(guò)從磁盤(pán)讀取內容來(lái)驗證這些頁(yè)面。一旦pageins完成,文件系統分解原始數據來(lái)提取請求的文件內容或屬性信息。需要注意的是,這個(gè)文件系統數據將像其它內存頁(yè)一樣被緩存起來(lái)。在隨后的I/O請求中,一些數據或所有文件數據仍然保存在物理內存中,可以直接重用不需要從磁盤(pán)重讀。
文件加鎖是一種機制,一個(gè)進(jìn)程可以阻止其它進(jìn)程訪(fǎng)問(wèn)一個(gè)文件或限制其它進(jìn)程訪(fǎng)問(wèn)該文件。雖然名為“文件鎖定”,意味著(zhù)鎖定整個(gè)文件(經(jīng)常做的)。鎖定通??梢栽谝粋€(gè)更細粒度的水平程序員關(guān)注猿圈:CodePush。隨著(zhù)粒度下降到字節級,文件的區域通常會(huì )被鎖定。鎖與特定文件相關(guān)聯(lián),起始于文件的指定字節位置并運行到指定的字節范圍。這一點(diǎn)很重要,因為它允許多個(gè)進(jìn)程協(xié)作訪(fǎng)問(wèn)文件的特定區域而不妨礙別的進(jìn)程在文件其它位置操作。
文件鎖有兩種形式:共享和獨占。多個(gè)共享鎖可以同時(shí)在相同的文件區域有效。另一方面,獨占鎖要求沒(méi)有其它鎖對請求的區域有效。
并非所有的I/O是面向塊的。還有流I/O,它是管道的原型,必須順序訪(fǎng)問(wèn)I/O數據流的字節。常見(jiàn)的數據流有TTY(控制臺)設備、打印端口和網(wǎng)絡(luò )連接。
數據流通常但不一定比塊設備慢,提供間歇性輸入。大多數操作系統允許在非阻塞模式下工作。允許一個(gè)進(jìn)程檢查數據流的輸入是否可用,不必在不可用時(shí)發(fā)生阻塞。這種管理允許進(jìn)程在輸入到達時(shí)進(jìn)行處理,在輸入流空閑時(shí)可以執行其他功能。
比非阻塞模式更進(jìn)一步的是有條件的選擇(readiness selection)。它類(lèi)似于非阻塞模式(并且通常建立在非阻塞模式基礎上),但是減輕了操作系統檢查流是否就緒準的負擔。操作系統可以被告知觀(guān)察流集合,并向進(jìn)程返回哪個(gè)流準備好的指令。這種能力允許進(jìn)程通過(guò)利用操作系統返回 的準備信息,使用通用代碼和單個(gè)線(xiàn)程復用多個(gè)活動(dòng)流。這種方式被廣泛用于網(wǎng)絡(luò )服務(wù)器,以便處理大量的網(wǎng)絡(luò )連接。準備選擇對于大容量擴展是至關(guān)重要的。
到此為止,對這個(gè)非常復雜的話(huà)題有一大堆技術(shù)術(shù)語(yǔ)。
如果你有想法和疑問(wèn),請給給我發(fā)評論。
學(xué)習快樂(lè )??!
原文鏈接: howtodoinjava 翻譯: ImportNew.com - liken
譯文鏈接: http://www.importnew.com/14111.html
聯(lián)系客服