NIO的直接快取區與非直接分快取區
直接快取區是在虛擬機器記憶體外,開闢的記憶體,IO操作直接進行,不再對其進行復制,但建立和銷燬開銷大
非直接快取區在虛擬機器記憶體中建立,易回收,但佔用虛擬機器記憶體開銷,處理中有複製過程(見非直接緩衝區寫入步驟)
非直接緩衝區寫入步驟:
1.建立一個臨時的直接ByteBuffer物件。
2.將非直接緩衝區的內容複製到臨時緩衝中。
3.使用臨時緩衝區執行低層次I/O操作。
4.臨時緩衝區物件離開作用域,並最終成為被回收的無用資料。
如果採用直接緩衝區會少一次複製過程,如果需要迴圈使用緩衝區,用直接緩衝區可以很大地提高效能。雖然直接緩衝區使JVM可以進行高效的I/o操作,但它使用的記憶體是作業系統分配的,繞過了JVM堆疊,建立和銷燬比堆疊上的緩衝區要更大的開銷。
Java API解釋:
直接與 非直接緩衝區
位元組緩衝區要麼是直接的,要麼是非直接的。如果為直接位元組緩衝區,則 Java 虛擬機器會盡最大努力直接在此緩衝區上執行本機 I/O 操作。也就是說,在每次呼叫基礎作業系統的一個本機 I/O 操作之前(或之後),虛擬機器都會盡量避免將緩衝區的內容複製到中間緩衝區中(或從中間緩衝區中複製內容)。
直接位元組緩衝區可以通過呼叫此類的allocateDirect
工廠方法來建立。此方法返回的緩衝區進行分配和取消分配所需成本通常高於非直接緩衝區。直接緩衝區的內容可以駐留在常規的垃圾回收堆之外,因此,它們對應用程式的記憶體需求量造成的影響可能並不明顯。所以,建議將直接緩衝區主要分配給那些易受基礎系統的本機
I/O 操作影響的大型、持久的緩衝區。一般情況下,最好僅在直接緩衝區能在程式效能方面帶來明顯好處時分配它們。
直接位元組緩衝區還可以通過 mapping 將檔案區域直接對映到記憶體中來建立。Java 平臺的實現有助於通過 JNI 從本機程式碼建立直接位元組緩衝區。如果以上這些緩衝區中的某個緩衝區例項指的是不可訪問的記憶體區域,則試圖訪問該區域不會更改該緩衝區的內容,並且將會在訪問期間或稍後的某個時間導致丟擲不確定的異常。
位元組緩衝區是直接緩衝區還是非直接緩衝區可通過呼叫其 isDirect
方法來確定。提供此方法是為了能夠在效能關鍵型程式碼中執行顯式緩衝區管理。