溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java?NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么

發(fā)布時間:2021-12-07 18:41:18 來源:億速云 閱讀:193 作者:iii 欄目:開發(fā)技術

這篇文章主要講解了“Java NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么”吧!

定義

Java?NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么

  1. java nio字節(jié)緩沖區(qū)要么是直接的,要么是非直接的。如果為直接字節(jié)緩沖區(qū),則java虛擬機會盡最大努力直接在此緩沖區(qū)上執(zhí)行本機的IO操作,也就是說,在每次調用基礎操作系統(tǒng)的一個本機IO操作前后,虛擬機都會盡量避免將內核緩沖區(qū)內容復制到用戶進程緩沖區(qū)中,或者反過來,盡量避免從用戶進程緩沖區(qū)復制到內核緩沖區(qū)中。

  2. 直接緩沖區(qū)可以通過調用該緩沖區(qū)類的allocateDirect(int capacity) 方法創(chuàng)建,此方法返回的緩沖區(qū)進行分配和取消分配所需的成本要高于非直接緩沖區(qū)。直接緩沖區(qū)的內容駐留在垃圾回收堆之外,因此他們對應用程序內存(JVM內存)需求不大。所以建議直接緩沖區(qū)要分配給那些大型,持久(就是緩沖區(qū)的數(shù)據(jù)會被重復利用)的緩沖區(qū),一般情況下,最好僅在直接緩沖區(qū)能在程序性能帶來非常明顯的好處時才分配它們。

  3. 直接緩沖區(qū)還可以通過FileCHannel的map()方法將文件區(qū)域映射到內存中來創(chuàng)建,該方法返回MappedByteBuffer。java平臺的實現(xiàn)有助于通過JNI本地代碼創(chuàng)建直接字節(jié)緩沖區(qū),如果以上這些緩沖區(qū)中某個緩沖區(qū)實例指向的是不可訪問的內存區(qū)域,則試圖方法該區(qū)域不會更改緩沖區(qū)的內容,并且會在訪問期間或者稍后的某個時間導致報出不確定性異常。

  4. 字節(jié)緩沖區(qū)是直接緩沖區(qū)還是非直接緩沖區(qū)可以通過調用其isDIrect()方法來判斷。

基于NIO的本地IO直接內存使用:

傳統(tǒng)IO對文件數(shù)據(jù)進行讀寫的流程:

Java?NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么

流程說明(以上是應用程序完成一次文件拷貝的流程):

  1. 應用進程發(fā)起一個讀請求系統(tǒng)調用,然后進程切換到內核態(tài)。

  2. DMA把磁盤數(shù)據(jù)復制到內核緩沖區(qū)中。

  3. 內核把緩沖區(qū)數(shù)據(jù)復制到用戶緩沖區(qū)中。

  4. 進程切換到用戶態(tài)。

  5. 應用進程發(fā)起一個寫請求系統(tǒng)調用,然后進程切換到內核態(tài)。

  6. 內核把用戶緩沖區(qū)數(shù)據(jù)復制到內核緩沖區(qū)。

  7. DMA把內核緩沖區(qū)數(shù)據(jù)復制到磁盤上。

  8. 返回。

以上流程一共進行了四次上下文切換,四次數(shù)據(jù)拷貝。

使用mmap實現(xiàn)對傳統(tǒng)文件IO優(yōu)化。

mmap:通過把內核緩沖區(qū)和用戶緩沖區(qū)映射在物理內存上映射為同一地址空間。這樣就不用對數(shù)據(jù)進行復制了。

Java?NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么

這個是傳統(tǒng)的:

Java?NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么

使用mmap后的IO大致流程:

Java?NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么

數(shù)據(jù)拷貝次數(shù)從4次縮短到了兩次。

相關API demo以及比較:詳細api解釋可以查看Java NIO學習篇之通道FileChannel詳解

//使用直接緩沖區(qū)API進行一個700多M的文件進行拷貝
public static void testDirect(){
        try {
            long start = System.currentTimeMillis();
            FileChannel srcFileChannel = FileChannel.open(Paths.get("C:\\Users\\Yehaocong\\Desktop\\test\\95462017-1-64.flv"), StandardOpenOption.READ);
            FileChannel destFileChannel = FileChannel.open(Paths.get("C:\\Users\\Yehaocong\\Desktop\\test\\95462017-1-64-cp1.flv"),StandardOpenOption.CREATE,
                    StandardOpenOption.WRITE,StandardOpenOption.READ);
            MappedByteBuffer srcByteBuffer = srcFileChannel.map(FileChannel.MapMode.READ_ONLY,0,srcFileChannel.size());
            MappedByteBuffer descByteBuffer = destFileChannel.map(FileChannel.MapMode.READ_WRITE,0,srcFileChannel.size());
            descByteBuffer.put(srcByteBuffer);
            srcFileChannel.close();
            destFileChannel.close();
            System.out.println("直接緩沖區(qū)耗時:" + (System.currentTimeMillis()-start));
      } catch (IOException e) {
            e.printStackTrace();
        }
    }

public static void testSimpleIO(){
        try {
            long start = System.currentTimeMillis();
            FileChannel srcFileChannel = FileChannel.open(Paths.get("C:\\Users\\Yehaocong\\Desktop\\test\\95462017-1-64.flv"), StandardOpenOption.READ);
            FileChannel destFileChannel = FileChannel.open(Paths.get("C:\\Users\\Yehaocong\\Desktop\\test\\95462017-1-64-cp.flv"),StandardOpenOption.CREATE,
                    StandardOpenOption.WRITE,StandardOpenOption.READ);
            ByteBuffer byteBuffer = ByteBuffer.allocate((int) srcFileChannel.size());
            while (srcFileChannel.read(byteBuffer)!=-1){
                byteBuffer.flip();
                destFileChannel.write(byteBuffer);
                byteBuffer.clear();
            }


            srcFileChannel.close();
            destFileChannel.close();

            System.out.println("非緩沖區(qū)耗時:" + (System.currentTimeMillis()-start));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

執(zhí)行結果:

 Java?NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么

Java?NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么

感謝各位的閱讀,以上就是“Java NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么”的內容了,經過本文的學習后,相信大家對Java NIO直接緩沖區(qū)和非直接緩沖區(qū)是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI