<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Java I/O 如何在較低級別上內部工作? > 原文: [https://howtodoinjava.com/java/io/how-java-io-works-internally-at-lower-level/](https://howtodoinjava.com/java/io/how-java-io-works-internally-at-lower-level/) 這篇博客文章主要討論與 I/O 相關的事物在較低級別的工作方式。 這篇文章供那些想知道如何在機器級別映射 [**Java I/O**](//howtodoinjava.com "java io") 操作的讀者使用; 以及您的應用程序在運行時,硬件在所有時間內的所有工作。 我假設您熟悉基本的 IO 操作,例如讀取文件,通過 Java I/O API 寫入文件; 因為那超出了這篇文章的范圍。 ```java Table of Contents Buffer Handling and Kernel vs User Space Virtual Memory Memory Paging File/Block Oriented I/O File Locking Stream Oriented I/O ``` ## 緩沖區處理和內核與用戶空間 緩沖區以及如何處理緩沖區是所有 I/O 的基礎。 **術語“輸入/輸出”僅意味著將數據移入和移出緩沖區。** 始終要記住這一點。 通常,進程通過請求操作系統從緩沖區中清空數據(*寫入操作*)或向緩沖區中填充數據(*讀取操作*)來執行 I/O。 以上是 I/O 概念的全部總結。 操作系統內部執行這些傳輸的機制可能非常復雜,但是從概念上講,它非常簡單,我們將在本文中討論其中的一小部分。 ![data buffering at os level](https://img.kancloud.cn/7e/d0/7ed0e564f88215287fc45ce90ee857ae_328x99.png) 上圖顯示了塊數據如何從外部源(例如硬盤)移動到正在運行的進程(例如 RAM)內部的存儲區的簡化“邏輯”圖。 首先,該進程通過進行`read()`系統調用來請求填充其緩沖區。 此調用導致內核向磁盤控制器硬件發出命令以從磁盤獲取數據。 磁盤控制器通過 [**DMA**](https://en.wikipedia.org/wiki/Direct_memory_access "dma") 將數據直接寫入內核內存緩沖區,而無需主 CPU 的進一步協助。 磁盤控制器完成緩沖區填充后,內核將數據從內核空間中的臨時緩沖區復制到進程指定的緩沖區中; 當它請求`read()`操作時。 需要注意的一件事是內核嘗試緩存和/或預取數據,因此進程請求的數據可能已經在內核空間中可用。 如果是這樣,則將過程所請求的數據復制出來。 如果數據不可用,則該過程將暫停,而內核將數據帶入內存。 ## 虛擬內存 您必須已經多次聽說虛擬內存。 讓我對它進行一些思考。 所有現代操作系統都使用虛擬內存。 虛擬內存意味著使用人工或虛擬地址代替物理(硬件 RAM)內存地址。 虛擬內存具有兩個重要優點: 1)多個虛擬地址可以引用相同的物理內存位置。 2)虛擬內存空間可能大于可用的實際硬件內存。 在上一節中,從內核空間復制到最終用戶緩沖區必須看起來像是額外的工作。 為什么不告訴磁盤控制器將其直接發送到用戶空間中的緩沖區? 嗯,這是通過使用虛擬內存來完成的,它的優勢是上面的 1。 通過將內核空間地址映射到與用戶空間中虛擬地址相同的物理地址,DMA 硬件(只能訪問物理內存地址)可以填充一個緩沖區,該緩沖區同時對內核和用戶空間進程可見。 ![virtual memory](https://img.kancloud.cn/7d/f0/7df0d8b6d8e23db9adffbdae70b4a3f4_332x155.png) 這消除了內核空間和用戶空間之間的副本,但是需要內核空間和用戶緩沖區共享相同的頁面對齊方式。 緩沖區還必須是磁盤控制器使用的塊大小的倍數(通常為 512 字節磁盤扇區)。 操作系統將其內存地址空間劃分為頁面,頁面是固定大小的字節組。 這些內存頁始終是磁盤塊大小的倍數,通常為 2 的冪(這簡化了尋址)。 典型的內存頁面大小為 1,024、2,048 和 4,096 字節。 虛擬和物理內存頁面大小始終相同。 ## 內存分頁 為了支持虛擬內存的第二個優勢(可尋址空間大于物理內存),有必要進行虛擬內存分頁(通常稱為交換)。 這是一種方案,通過該方案可以將虛擬內存空間的頁面持久保存到外部磁盤存儲中,從而在物理內存中為其他虛擬頁面騰出空間。 本質上,物理內存充當頁面調度區域的緩存,這是磁盤上的空間,當磁盤空間被迫退出物理內存時,該空間用于存儲內存頁面的內容。 將內存頁面大小調整為磁盤塊大小的倍數,可使內核向磁盤控制器硬件發出直接命令,以將內存頁面寫入磁盤或在需要時重新加載它們。 事實證明,所有磁盤 I/O 都是在頁面級別完成的。 在現代的分頁操作系統中,這是數據在磁盤和物理內存之間移動的唯一方式。 現代 CPU 包含一個稱為[**內存管理單元(MMU)**](https://en.wikipedia.org/wiki/Memory_management_unit "MMU")的子系統。 該設備在邏輯上位于 CPU 和物理內存之間。 它包含將虛擬地址轉換為物理內存地址所需的映射信息。 當 CPU 引用一個內存位置時,MMU 會確定該位置所在的頁面(通常通過移動或屏蔽地址值的位)并將該虛擬頁面號轉換為物理頁面號(此操作在硬件中完成,并且非常復雜)和快速)。 ## 面向文件/塊的 I/O 文件 I/O 始終在文件系統的上下文中發生。 文件系統與磁盤完全不同。 磁盤將數據存儲在扇區中,通常每個扇區 512 字節。 它們是對文件語義一無所知的硬件設備。 它們只是提供了許多可以存儲數據的插槽。 在這方面,磁盤的扇區類似于內存頁面; 它們都具有統一的大小,并且可以作為一個大數組尋址。 另一方面,文件系統是更高級別的抽象。 文件系統是整理和解釋存儲在磁盤(或某些其他隨機訪問的,面向塊的設備)上的數據的特殊方法。 您編寫的代碼幾乎總是與文件系統交互,而不是直接與磁盤交互。 它是定義文件名,路徑,文件,文件屬性等的抽象的文件系統。 文件系統(在硬盤中)組織一系列大小一致的數據塊。 一些塊存儲元信息,例如空閑塊,目錄,索引的映射等。其他塊包含實際文件數據。 有關單個文件的元信息描述了哪些塊包含文件數據,數據結束于何處,數據的最后更新時間等。當用戶進程發出讀取文件數據的請求時,文件系統實現將確定數據在磁盤上的確切位置。 然后,它將采取措施將這些磁盤扇區放入內存。 文件系統還具有頁面的概念,其大小可以與基本內存頁面相同,也可以是其倍數。 典型的文件系統頁面大小為 2,048 至 8,192 字節,并且始終是基本內存頁面大小的倍數。 分頁文件系統如何執行 I/O 歸結為以下邏輯步驟: 1. 確定請求跨越哪個文件系統頁面(磁盤扇區組)。 磁盤上的文件內容和/或元數據可能分布在多個文件系統頁面上,并且這些頁面可能是不連續的。 2. 在內核空間中分配足夠的內存頁面以容納已標識的文件系統頁面。 3. 在這些內存頁面和磁盤上的文件系統頁面之間建立映射。 4. 為每個內存頁面生成頁面錯誤。 5. 虛擬內存系統會捕獲頁面錯誤,并調度 pageins 通過從磁盤讀取其內容來驗證這些頁面。 6. 一旦 pageins 完成,文件系統將分解原始數據以提取請求的文件內容或屬性信息。 請注意,此文件系統數據將像其他內存頁面一樣被緩存。 在后續的 I/O 請求中,部分或全部文件數據可能仍存在于物理內存中,并且可以重新使用而無需從磁盤重新讀取。 ## 文件鎖定 文件鎖定是一種方案,通過該方案,一個進程可以阻止其他進程訪問文件或限制其他進程訪問該文件的方式。 雖然“文件鎖定”一詞的含義是鎖定整個文件(并且通常這樣做),但鎖定通常可以在更細粒度的級別上進行。 文件區域通常是鎖定的,粒度低至字節級別。 鎖與特定文件相關聯,該鎖從該文件中的特定字節位置開始,并在特定字節范圍內運行。 這很重要,因為它允許許多進程協調對文件特定區域的訪問,而不會妨礙其他進程在文件中的其他位置工作。 文件鎖有兩種形式:**共享**和**獨占**。 多個共享鎖可能對同一文件區域同時生效。 另一方面,排他鎖要求對請求的區域沒有其他鎖生效。 ## 流 I/O 并非所有的 I/O 都是面向塊的。 還有流 I/O,它是在管道上建模的。 I/O 流的字節必須順序訪問。 TTY(控制臺)設備,打印機端口和網絡連接是流的常見示例。 流通常(但不一定)比塊設備慢,并且通常是間歇輸入的來源。 大多數操作系統允許將流置于非阻塞模式,這允許進程檢查輸入是否在流上可用,而不會卡住當前是否可用。 這種特性允許進程在輸入到達時處理輸入,但在輸入流空閑時執行其他函數。 超越非阻塞模式的一步是進行**準備就緒選擇**的能力。 這類似于非阻塞模式(并且通常在非阻塞模式的基礎上構建),但將檢查流是否已準備就緒的檢查分擔給操作系統。 可以告訴操作系統觀看流的集合,并向這些流中的哪些流準備就緒的過程返回指示。 此特性允許進程利用操作系統返回的就緒信息,使用通用代碼和單個線程多路復用許多活動流。 這在網絡服務器中被廣泛使用以處理大量的網絡連接。 準備就緒選擇對于大批量縮放至關重要。 這就是這個非常復雜的主題,包含大量技術詞匯 給我評論您的想法和疑問。 **祝您學習愉快!**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看