直接與非直接緩衝區
字節緩衝區跟其他緩衝區類型最明顯的不同在於,它們可以成爲通道所執行的 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
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!