ByteBuffer.allocateDirect vs ByteBuffer.allocate 數組
操做系統的IO機制 緩存
操做系統在內存區域上執行IO操做,這些內存區域是連續的字節。毫無疑問只有字節緩衝區纔有資格參與IO操做的。一樣操做系統會直接訪問進程空間,包括JVM進程,傳輸數據。JVM內部,字節數組可能不是連續的,或者GC任意時刻會移動這些字節。Java內部數組是對象,對象內部數據存儲的方式,是跟JVM實現相關的。 性能
引入Direct Buffer 優化
出於這個緣由,引入了direct buffer。direct buffer就是爲了和channel和本地IO例程交互。direct buffer的實現會盡可能讓channel直接使用,本地操做系統代碼可以直接讀寫。
spa
利弊 操作系統
直接緩衝區一般是IO操做的最佳選擇,是JVM可以使用的最高效的IO機制。non-direct緩衝區能夠傳遞給channel,但一般會帶來性能損耗。一般non-direct緩衝區不是本地IO操做的直接目標。若是讓channel寫non-direct ByteBuffer,channel會隱含的執行下列步驟:
設計
建立臨時的direct ByteBuffer
對象
複製non-direct buffer中的內容到臨時buffer
進程
使用臨時buffer執行IO操做
內存
臨時buffer不被引用,最終被垃圾收集
這會潛在的致使每次IO操做中的緩衝區複製和Object Churn,這正是咱們想避免的。然而取決於實現,事情可能並不會這麼壞。JVM運行時可能會緩存和重用direct緩衝區,或着其它技巧來提升吞吐量。若是建立只使用一次的緩衝區,這二者的區別並不明顯。若是在高性能的場景中頻繁使用buffer,那麼最好使用direct緩衝區。
direct緩衝區最適合IO,可是可能建立更加耗時。direct緩衝區使用的內存,繞過了JVM堆,經過本地代碼調用分配。建立和銷燬都要比駐留在JVM堆裏的緩衝區更加耗時(依賴於操做系統和JVM實現)。direct緩衝區使用的內存不受垃圾收集的控制,由於它們在JVM堆的外部。
總結
使用direct仍是non-direct的性能考慮依賴於JVM,操做系統,和應用代碼。在JVM堆外分配內存,把應用受制於JVM不能監管的一些額外機制。讓額外的一些機制起做用,必定要保證你得到了想要的效果。我推薦古老的設計哲學,「首先讓他工做,而後讓他更快」。不要提早擔憂優化,首先關注應用的正確。JVM實現可能會執行一些優化,給你想要的性能,這樣就免除了開發者的負擔。
原文 From:http://stackoverflow.com/questions/5670862/bytebuffer-allocate-vs-bytebuffer-allocatedirect