受」誤解「的Java AIO

爲何說 AIO 受」誤解「,雖然這個」誤解「被打上了雙引號,但仍是不得不認可它的發展情況並很差。AIO 是 Java 7 開始提供的新特性,而這個」新特性「到現在都成了陳年老酒還鮮有人去品味它。要知道 Java 7 但是在 2011年7月份發佈的,市面上基於 AIO 實現的通訊框架居然寥寥無幾,關於這項技術的介紹文章也廣泛比較粗略。經過閱讀那些介紹 AIO 的文章,彷佛從學術層面你們就不怎麼待見這項技術。html

做爲 AIO 的學習者、受益者,我以爲有必要先對網上的一些 」偏見「 表達一下本身的觀點。若是能有幸在認知上搭成共識,以後的學習交流會更加順暢一點。一般偏見源於比較,AIO 與 BIO、NIO 的對比明細如表所示。緩存

受」誤解「的Java AIO


誤解一

經過上表的比較能夠看出 AIO 的性價比應該是優於 NIO 的,而實際狀況倒是大多數人更偏心與 NIO,準確的說應該是偏心 NIO 通訊框架:Netty。這本無可厚非,Netty 確實是一款很是優秀的項目,但是不少人錯誤的解讀了 Netty 在 Github 上關於不支持 AIO 的理由,這更加遏制了 AIO 的發展。服務器

Not faster than NIO (epoll) on unix systems (which is true)併發

這句話表達的本意應該是:NIO 和 AIO 在 unix 系統上使用的都是 epoll 模式,本質都是同樣的。但Not faster than NIO在必定程度上會讓人誤解爲 AIO 沒 NIO 快。 這裏能夠採用假設的方式來論證這個觀點是不成立的。框架

假設:ide

epoll 表現的性能爲 x=100;高併發

通訊框架由於要解決併發調度與資源分配問題,對 epoll 進行封裝後會存在必定的性能損耗,以 y 表示。性能

最終性能表現結果應該是 r=x-y。學習

論證:.net

  1. 某款 NIO 框架基於 epoll 封裝後的性能損耗值:y=5,則它所發揮的最終性能爲:x-y=95。
  2. 若是有一款 AIO 框架能將性能損耗值控制在:y=(0,5) ,那最終性能便高於 NIO 框架。如 y>5,則性能低於 NIO 框架。

結論:

以底層模型是 kqueue、epoll、select 仍是 IOCP 來比較 NIO 和 AIO 的性能是不嚴謹的,決定權在於框架實現能挖掘出多少基礎能力。不然一樣採用 NIO 技術,爲何不一樣的框架仍是會有高低之分。

誤解二

Linux 系統的 AIO 還不成熟。若是是這個緣由的話,不妨先看下:http://lse.sourceforge.net/io/aio.html,其中核心的一句話:Support for kernel AIO has been included in the 2.6 Linux kernel.請注意,Linux 內核自 2.6 版本起已支持AIO模式。

這是個很奇怪的現象,彷佛曾經不支持 AIO 就以爲永遠不支持,曾經出現的 bug 就永遠存在。正如 JAVA NIO 的空輪訓 bug ,現在都已經發展到 Java 13 了,依舊還有人堅信這個 bug 一直在。坦白的講,我沒有去驗證過 Java AIO 在 Linux 環境下是不是真正意義的 AIO,也沒有復現出 NIO 的空輪訓 bug。但若是由於某種緣由放棄持續學習,那對於事物的認知和見識就只能停留在過去。

因此」Linux 系統的 AIO 還不成熟「也不會成爲我拋棄 AIO 的理由。

誤解三

須要爲每個鏈接預先分配讀緩存。這個確實是客觀存在的狀況,AIO 的使用方式是調用讀寫接口將ByteBuffer對象註冊進去,當事件完成後以回調的形式觸發CompletionHandler,因此必需要事先分配好緩存空間。

可是有一個細節可能會被你們忽略掉,即使採用 NIO,當遇到半包/粘包的的狀況,仍是須要有一個緩存對象來暫存這份不完整的數據。尤爲在高併發場景下,半包/粘包現象很容易加重,此時 NIO 須要分配的緩存並不比 AIO 節省多少。

即便假設理想狀態下並不存在半包/粘包問題,AIO 通訊的預分配形式又能額外消耗多少內存。爲每一個鏈接分配 1024 字節的讀緩存,在1萬個併發鏈接的條件下也才消耗不到 10MB 內存,試問現實場景下一臺 Java 應用服務器須要同時支撐多少個併發,1萬?5萬?10萬?。

目前已知的通訊框架一般會配備內存池,在這種前提下 AIO 也只是將內存池中的資源提早利用起來而已。在同等的內存池配置,相同的併發壓力下,若是 AIO 暴露出內存方面的問題,咱們再來作 AIO 和 NIO 的選擇。

總結

本文並非要將 NIO 和 AIO 對立起來,這兩項技術都很是吸引人,喜歡技術的朋友能夠在這方面鑽研好久。我的推薦純粹出於學習優先考慮 NIO,由於難度更高,更具挑戰性,將要面臨和須要解決的問題更多。在學習的過程當中若是遇到困惑,能夠再去翻一下 AIO 的源碼,裏面有不少值得借鑑的設計。

相關文章
相關標籤/搜索