1. 程式人生 > >JDK各版本I/O分析

JDK各版本I/O分析

全文總結於李林鋒老師的《Netty權威指南》,連結如下:


Linux系統I/O的實現

Linux阻塞
linux非阻塞
Linux I/O複用 Linux提供select/poll,程序通過將一個或多個fd(file descriptor,檔案描述符,Linux核心為高效管理已被開啟的“檔案”所建立的索引)傳遞給select或poll系統呼叫,阻塞在select操作上,這樣select/poll可以幫我們偵測多個fd是否處於就緒狀態。select/poll是順序掃描fd是否就緒,而且支援的fd數量有限,因此它的使用受到制約。Linux還提供了一個epoll系統呼叫,epoll使用基於時間驅動方式代替順序掃描,因此效能更高。當有fd就緒時,立即回撥函式rollback。

Linux訊號驅動 首先開啟套介面訊號驅動I/O功能,並通過系統呼叫sigaction執行一個訊號處理函式(此係統呼叫立即返回,程序繼續工作,非阻塞)。當資料準備就緒時,就為該程序生成一個sigio訊號,通過訊號回撥通知應用程式呼叫recvfrom來讀取資料,並通知主迴圈函式處理資料。
非同步I/O 告知核心啟動某個操作,並讓核心在整個操作完成後(包括將資料從核心複製到使用者自己的緩衝區)通知我們。這種模型與訊號驅動模型區別是:訊號驅動I/O由核心通知我們何時可以開始一個I/O操作:非同步I/O模型由核心通知我們I/O操作何時已經完成。
I/O多路複用技術通過把多個I/O的阻塞複用到同一個select的阻塞上,從而使得系統在單執行緒的情況下可以同時處理多個客戶端請求。與傳統的多執行緒模型相比,
I/O多路複用的最大優勢是系統開銷小,不需要建立新的額外執行緒,降低了系統維護工作量,節省了系統資源

應用場景: 1.伺服器需要同時處理多個處於監聽狀態或者多個連線狀態的套接字; 2.伺服器需要同時處理多種網路協議的套接字;

目前支援有select、pselect、poll和epoll。 其中,epoll相比select的優點;

1.支援一個程序開啟的socket描述符(fd)不受限制(僅受限於作業系統的最大檔案控制代碼數),select受限於fd_setsize,預設1024;

2.I/O效率不會隨著fd數目的增加而下降。使用select/poll時,當擁有一個很大的socket集合,由於網路延時和鏈路空閒,某時刻只有少部分socket是活躍的,而select/poll每次呼叫都會現行掃描全部的集合,效率低下。epoll是根據每個fd上的callback函式實現,只有活躍的socket才主動呼叫callback函式;

3.使用mmap加速核心與使用者空間的訊息傳遞;

4.epoll的API更簡單。



Java網路程式設計模型

網路程式設計模型說白了Client/Server模型,兩個程序之間通訊。服務端提供IP地址和介面,客戶端通過連線操作向服務端監聽的介面發起請求,通過三次握手建立連線,如果連線建立成功,雙方就可以通過網路套接字(socket)進行通訊。下面說說在JDK各版本網路程式設計中對IO的支援:

IO

即BIO(阻塞IO),在JDK1.4以前java都是採用這種方式網路通訊的。同步阻塞I/O最大的問題:每當有一個新的客戶端請求接入時,服務端必須建立一個新的執行緒處理新接入的客戶端鏈路,一個執行緒只能處理一個客戶端連線。

我們可以基於BIO自行實現偽非同步I/O通訊框架:採用執行緒池和任務佇列。當有新的客戶端接入時,將客戶端的socket封裝成一個task(實現Runnable介面)投遞到後端你的執行緒池中進行處理,JDK執行緒池維護一個訊息佇列和N個活躍執行緒,對訊息佇列中的任務進行處理。

當這種實現方式沒有從根本上解決同步I/O導致的通訊執行緒阻塞問題,通訊對方返回應答時間過長會引發級聯故障。於是jdk後來提出了NIO。


NIO

即New IO,在JDK 1.4正式提出。NIO提供了SocketChannel和ServerSocketChannel兩種不同的套接字通道實現。這兩種新增的通道都支援阻塞和非阻塞兩種模式。阻塞模式使用簡單,但是效能和可靠性不好。非阻塞模型相反。一般來說,低負載、低併發的應用程式可使用同步阻塞I/O以降低程式設計複雜度。

NIO提供了高速的、面向塊的I/O。通過定義包含資料的類,以及通過以塊的形式處理這些資料,NIO不用使用本機程式碼就可以利用低階優化。重點關注如下概念:

緩衝區Buffer 包含要寫入和讀出的資料。在NIO庫中,所有的資料都是用緩衝區處理的。緩衝區實質上是一個數組,通常是一個位元組陣列(ByteBuffer),也可以使用其他種類的陣列。緩衝區還提供了對資料的結構化訪問以及維護讀寫位置(limit)等資訊。 基本所有java基本型別(除了boolean)都對應有個緩衝區。因為大多數標準I/O操作都使用ByteBuffer,所以它還提供了一些特有的操作,以方便網路讀寫。


通道Channel  網路資料通過Channel讀取和寫入。和流不同之處在於通道是雙向的,因為Channel是全雙工(Full Duplex,是通訊傳輸的一個術語。通訊允許資料在兩個方向上同時傳輸,它在能力上相當於兩個單工通訊方式的結合),所以它可以比流更好地對映底層作業系統的API。


Channel大致可以分為兩大類:用於網路讀寫的SelectableChannel和用於檔案操作的FileChannel。 多路複用器Selector 提供選擇已經就緒的任務的能力。Selector會不斷地輪詢註冊在其上的Channel,如果某個Channel上面發生讀或寫事件,這個Channel就處於就緒狀態,會被Selector輪詢出來,然後通過SelectionKey可以獲取就緒Channel的集合,進行後續的I/O操作。 一個多路複用器Selector可以同時輪詢多個Channel,JDK使用了epoll()代替了傳統的select實現,所以沒有最大連線控制代碼1024/2048的限制。這就是說,只需要一個執行緒負責Selector的輪詢,就可以接入成千上萬的客戶端。



AIO


非同步通道提供兩種方式獲取操作結果:
1.通過java.util.concurrent.Future類來標識非同步操作的結果; 2.在執行非同步操作的時候傳入一個java.nio.channels; Completionhandler介面的實現類作為操作完成的回撥。 它的非同步套接字通道是真正的非同步非阻塞I/O,對應於UNIX網路程式設計中的事件驅動I/O(AIO)。它不需要通過多路複用器Selector對註冊的通道進行輪詢操作即可實現非同步讀寫。 非同步服務端通道AsychronousServerSocketChannel,非同步客戶端通道AsychronousSocketChannel

各版本IO總結

JDK1.4推出的NIO,Selector是基於select/poll模型實現的,基於I/O複用技術實現的非阻塞I/O,不是非同步I/O。在JDK1.5晚些版本優化了Selector實現使用了epoll替換了select/poll,上層的API沒有變化。但是仍舊沒有改變I/O模型。這裡需要注意epoll一個致命BUG:可能導致Selector空輪詢,最終CPU 100%。 JDK7提供的AIO提供了非同步的套接字通道,是真正的非同步I/O。在非同步I/O操作的時候可以傳遞訊號變數,當操作完成之後會回撥相關方法。 NIO實現的關鍵就是多路複用I/O技術,多路複用的核心就是通過Selector來輪詢註冊在其上的Channel,當發現某個或多個Channel處於就緒狀態,從阻塞狀態返回就緒的Channel的選擇鍵集合,進行I/O操作。

各版本IO的比較圖:


相關推薦

JDK版本I/O分析

全文總結於李林鋒老師的《Netty權威指南》,連結如下: Linux系統I/O的實現 Linux阻塞 linux非阻塞 Linux I/O複用 Linux提供select/p

JDK版本新增的主要特性

rmi rop j2se 嵌入式數據庫 應用 rdquo 數字 char htable JDK1.5新特性: 1.自動裝箱與拆箱: 2.枚舉 3.靜態導入,如:import staticjava.lang.System.out 4.可變參數(Varargs)

JDK版本特徵

JDK Version 1.0 1996-01-23 Oak(橡樹) 初代版本,偉大的一個里程碑,但是是純解釋執行,使用外掛JIT,效能比較差,執行速度慢。 JDK Version 1.1 1997-02-19 JDBC(Java DataBase Connect

JDK版本的新特性(jdk1.5~jdk1.8)

“Java is still not dead—and people are starting to figure that out.” 本教程將用帶註釋的簡單程式碼來描述新特性,你將看不到大片嚇人的文字。 一、介面的預設方法 Java 8允許我們給介面新增一個非抽象的方法實現,只需要使用 default關

JDK版本之間的特性區別

jdk1.5的新特性:1. 泛型   ArrayList list=new ArrayList()------>ArrayList<Integer>list=new ArrayList<Integer>();2 自動裝箱/拆箱   nt i=l

JDK版本釋出時間表

Java發展的時間表。 (版本號 名稱 中文名 釋出日期)   JDK 1.1.4 Sparkler 寶石 1997-09-12   JDK 1.1.5 Pumpkin 南瓜 1997-12-13   JDK 1.1.6 Abigail 阿比蓋爾–女子名

JDK版本區別整理(1.5-1.10)

本文主要整理自己覺得相對比較重要的一些版本區別。jdk1.5新特性1.自動裝箱與拆箱:原始型別與對應的包裝類不用顯式轉換ArrayList list=new ArrayList()----------->ArrayList<Integer>list=new

JDK版本的API下載

很全的各種版本JDK API下載,chm版本並帶搜尋。下載地址 http://www.allimant.org/javadoc/ 原帖地址:http://hi.baidu.com/luozhh/item/c5907b5dc04a983695eb05b3

深入理解JVM總結-JDK版本、JVC記憶體分配及溢位異常

第一部分 走近JAVA 第一章 走近Java 1.JDK1.5版本改動非常大,加入了自動裝箱、泛型、動態註解、列舉、可變長引數以及遍歷迴圈等。     JDK1.6提供動態語言支援,提供API編譯,且JVM中改進了鎖與同步、垃圾收集以及類載入等的演算法。    JDK1.7

作業系統效能計數器、CPU分析、磁碟I/O分析、記憶體分析

Window作業系統的主要效能技術器: Linux/UNIX 作業系統的主要效能計數器:   Linux系統的命令和UXIN的有些差別,在UNIX系統下的主要計數器監控命令是vmstat、iostat、top、sar、sag(圖形方式,需要XSe

Java Web 深入分析(4) Java I/O 深入分析

lock 異步 瓶頸 系統 基本結構 java 同步異步 nio -i I/O問題可以說是現在大部分web系統的瓶頸。我們要了解的java I/O(後面簡稱為(io)) io類庫的基本結構 -磁盤io的工作機制 -網絡io的工作機制 -NIO的工作方式 -同步異步、阻

MySQL在刪除表時I/O錯誤原因分析

隨機 是否 mysq let 影響 syn type src fc7 歡迎大家前往騰訊雲+社區,獲取更多騰訊海量技術實踐幹貨哦~ 本文由騰訊數據庫技術 發表於雲+社區專欄 問題現象 最近使用sysbench測試MySQL,由於測試時間較長,寫了一個腳本按prepare-

jdk 1.7系列 (二)文件 I/O 的基石 :Path

.com 隨心所欲 println prefix logs filesyste args 工具類 功能 在NIO.2的文件 I/O 中,Path是必須掌握的關鍵類之一。Path通常代表文件系統中的位置,比如 C:\Windows\System32 什麽是根目錄、絕對路

Java基礎總結之版本JDK新特性

JDK5新特性: (1)自動裝箱和拆箱: public class JDK5TNewFeatures { public static void main(String[] args) { Integer num = 10; int num2 = num; System.out

《深入分析Java Web技術內幕》讀後感之2- JAVA I/O NIO

一、Java I/O的基本架構 Java的I/O操作類在java.io包下,大概有80多個類,這些類可以分成以下4組: ▶ 基於位元組操作的I/O介面:InputStream和OutputStream ▶ 基於字元操作的I/O介面:Reader和Writer

linux效能分析工具介紹(CPU,記憶體,磁碟I/O,網路)

一. CPU效能評估 1.vmstat [-V] [-n] [depay [count]] -V : 打印出版本資訊,可選引數 -n : 在週期性迴圈輸出時,頭部資訊僅顯示一次 delay : 兩次輸出之間的時間間隔 count : 按照delay指定的時間間隔統計

《深入分析Java Web技術內幕》讀後感之JAVA I/O NIO

一、Java I/O的基本架構 Java的I/O操作類在java.io包下,大概有80多個類,這些類可以分成以下4組: ▶ 基於位元組操作的I/O介面:InputStream和OutputStream ▶ 基於字元操作的I/O介面:Reader和Writer ▶ 基於

深入分析 Java I/O 的工作機制

Java 的 I/O 類庫的基本架構 I/O 問題是任何程式語言都無法迴避的問題,可以說 I/O 問題是整個人機互動的核心問題,因為 I/O 是機器獲取和交換資訊的主要渠道。在當今這個資料大爆炸時代,I/O 問題尤其突出,很容易成為一個性能瓶頸。正因如此,所以 Java

一個磁碟I/O故障導致的AlwaysOn FailOver 過程梳理和分析

下面是我們在使用AlwaysOn過程中遇到的一個切換案例。這個案例發生在2014年8月,雖然時間相對久遠了,但是對我們學習理解AlwaysOn的FailOver原理和過程還是很有幫助的。本次FailOver的觸發原因是系統I/O問題。大家需要理解,作業系統I/O出現了問題不一定立即觸發SQL Server發生

20181114-2-Eclipse版本以及最低要求的jdk列表

小J有收集的癖好,同樣也有濃重的不作不死的強迫症。今天突然想整理一下Eclipse的列表。 版本號 代號 代號中文名 釋出年份 JDK版本要求 備註 Eclipse 3.1 IO 伊奧 2005 / 已不在