我剛剛看了一個wiki here,通道的一個說:JVM:什麼時候JVM需要複製內存內容
雖然理論上這些都是通用的數據結構,該 實現可以用於對齊選擇內存或分頁 特性,這些特性在Java中不可訪問。 通常,這將用於允許緩衝區內容佔用與底層操作系統使用的相同物理內存的 其本機I/O操作,從而允許最直接的傳輸機制,並且不需要任何額外的複製
我很好奇的話「消除任何額外的複製的需要」,什麼時候JVM需要這個,爲什麼NIO能避免呢?
我剛剛看了一個wiki here,通道的一個說:JVM:什麼時候JVM需要複製內存內容
雖然理論上這些都是通用的數據結構,該 實現可以用於對齊選擇內存或分頁 特性,這些特性在Java中不可訪問。 通常,這將用於允許緩衝區內容佔用與底層操作系統使用的相同物理內存的 其本機I/O操作,從而允許最直接的傳輸機制,並且不需要任何額外的複製
我很好奇的話「消除任何額外的複製的需要」,什麼時候JVM需要這個,爲什麼NIO能避免呢?
這是談論內核數據結構和用戶空間數據結構之間的直接映射;通常在兩者之間移動時需要上下文切換。但是,使用nio和直接緩衝區時,上下文切換(和相應的內存副本)不會發生。
爲什麼上下文切換需要內存拷貝?你能給我一個Java例子嗎?非常感謝。 – MrROY
從java.nio包API:
字節緩衝區可以被分配爲一個直接緩衝區,在這種情況下,Java虛擬機將直接在其上執行本機I/O操作的最大的努力。
實施例:
FileChannel fc = ...
ByteBuffer buf = ByteBuffer.allocateDirect(8192);
int n = fc.read(buf);
簡單地說,舊IO方式總是從內核到存儲器堆中複製數據。使用NIO允許使用內核直接映射文件/網絡流的緩衝區。結果:更少的內存消耗和更好的性能。
許多開發人員只知道單個JVM,即Oracle HotSpot JVM,並且在他們特別提到Oracle的HotSpot實現時會談到垃圾收集。但事情是檢查Bob's post
JDK 1.4引入的新輸入/輸出(NIO)庫在標準Java代碼中提供了高速的面向塊的I/O。
上NIO幾個點,
NIO API引入了一個新的基本I/O抽象,稱爲通道。通道表示與實體(如硬件設備,文件,網絡套接字)的開放連接。 當您使用API時FileChannel.transferTo()或FileChannel.transferFrom()JVM使用操作系統對DMA(直接內存訪問)的訪問,這是潛在的優勢。
據Ron Hitches
上Java NIO
直接緩衝區旨在與渠道互動和本地 I/O例程。他們盡最大努力將字節元素存儲在一個 存儲區中,該區域可以通過使用 本地代碼告知操作系統直接排空或填充內存區 區域,以用於直接訪問或原始訪問。
直接字節緩衝區通常是I/O操作的最佳選擇。通過 設計,它們支持可用於JVM的最高效的I/O機制。非本地字節緩衝區可以傳遞給通道,但這樣做可能會導致性能損失。一個 非直接緩衝區通常不可能成爲本地I/O操作的目標。
直接緩衝區對於I/O是最佳的,但是它們可能比非直接字節緩衝區更昂貴到 創建。直接緩衝區 使用的內存是通過調用本地操作系統專用 代碼來繞過標準JVM堆分配的。根據主機操作系統和JVM 實施情況,設置並拆除直接緩衝區可能會比 堆駐留緩衝區貴得多。直接緩衝區的內存存儲區域不 被垃圾回收,因爲他們是標準的 JVM堆
下面的教程會給你更深入的瞭解(尤其是2.4,2.4.2等)第2章 外http://blogimg.chinaunix.net/blog/upfile2/090901134800.pdf
http://stackoverflow.com/questions/5670862/bytebuffer-allocate-vs-bytebuffer-allocatedirect –