NIO之緩衝區【直接和非直接緩衝區】

直接與非直接緩衝區
  字節緩衝區跟其他緩衝區類型最明顯的不同在於,它們可以成爲通道所執行的 I/O 的源頭和/或目標。其實發現通道只接收ByteBuffer作爲參數這個將Channel的時候會發現。

類型    優點    缺點
直接緩衝區    在虛擬機內存外,開闢的內存,
IO操作直接進行,沒有再次複製    創建和銷燬開銷大
非直接緩衝區    在虛擬機內存中創建,易回收    但佔用虛擬機內存開銷,
處理中有複製過程。
直接緩衝區
  直接緩存區是在虛擬機內存外,開闢的內存,IO操作直接進行,不再對其進行復制,但創建和銷燬開銷大。

非直接緩衝區
  非直接緩存區在虛擬機內存中創建,易回收,但佔用虛擬機內存開銷,處理中有複製過程。

直接和非直接緩衝區解釋
  操作系統在內存區域中進行I/O操作,這些內存區域,就操作系統方面而言,是相連的字節序列。所以,只有字節緩衝區有資格參與I/O操作。操作系統會直接存取進程——在本例中是JVM進程的內存空間,以傳輸數據。這也意味着I/O操作的目標內存區域必須是連續的字節序列。在JVM中,字節數組可能不會在內存中連續存儲,或者無用存儲單元收集可能隨時對其進行移動。在Java中,數組是對象,而數據存儲在對象中的方式在不同的JVM實現中都各有不同。出於這一原因,引入了直接緩衝區的概念。

  直接字節緩衝區通常是I/O操作最好的選擇。在設計方面,它們支持JVM可用的最高效I/O機制。非直接字節緩衝區可以被傳遞給通道,但是這樣可能導致性能損耗。通常非直接緩衝不可能成爲一個本地I/O操作的目標。如果向一個通道中傳遞一個非直接ByteBuffer對象用於寫入,通道可能會在每次調用中隱含地進行下面的操作:

創建一個臨時的直接ByteBuffer對象。
將非直接緩衝區的內容複製到臨時緩衝中。
使用臨時緩衝區執行低層次I/O操作。
臨時緩衝區對象離開作用域,並最終成爲被回收的無用數據。
  直接緩衝區是I/O的最佳選擇,但可能比創建非直接緩衝區要花費更高的成本。直接緩衝區使用的內存是通過調用本地操作系統方面的代碼分配的,繞過了標準JVM堆棧。建立和銷燬直接緩衝區會明顯比具有堆棧的緩衝區更加破費,這取決於主操作系統以及JVM實現。直接緩衝區的內存區域不受無用存儲單元收集支配,因爲它們位於標準JVM堆棧之外。

  直接ByteBuffer是通過調用ByteBuffer.allocateDirect()函數產生的,注意用一個wrap()函數所創建的被包裝的緩衝區總是非直接的。

public abstract class ByteBuffer extends Buffer implements Comparable {
    // This is a partial API listing
    public static ByteBuffer allocate(int capacity)
    public static ByteBuffer allocateDirect(int capacity)
    public abstract boolean isDirect();
}
1
2
3
4
5
6
使用直接緩衝區有兩種方式:

緩衝區創建的時候分配的是直接緩衝區
在FileChannel上調用map()方法,將文件直接映射到內存中創建
--------------------- 
作者:波波烤鴨 
來源:CSDN 
原文:https://dpb-bobokaoya-sm.blog.csdn.net/article/details/89198608 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章