欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺析Java?NIO?直接緩沖區(qū)和非直接緩沖區(qū)

 更新時(shí)間:2021年11月30日 09:17:02   作者:我會(huì)努力變強(qiáng)的  
本篇文章主要為大家介紹了Java?NIO?中直接緩沖區(qū)和非直接緩沖區(qū)的定義以及使用流程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

定義

以上是書(shū)《深入理解java虛擬機(jī)對(duì)直接內(nèi)存的描述。直接緩沖區(qū)用的就是直接內(nèi)存。

  1. java nio字節(jié)緩沖區(qū)要么是直接的,要么是非直接的。如果為直接字節(jié)緩沖區(qū),則java虛擬機(jī)會(huì)盡最大努力直接在此緩沖區(qū)上執(zhí)行本機(jī)的IO操作,也就是說(shuō),在每次調(diào)用基礎(chǔ)操作系統(tǒng)的一個(gè)本機(jī)IO操作前后,虛擬機(jī)都會(huì)盡量避免將內(nèi)核緩沖區(qū)內(nèi)容復(fù)制到用戶進(jìn)程緩沖區(qū)中,或者反過(guò)來(lái),盡量避免從用戶進(jìn)程緩沖區(qū)復(fù)制到內(nèi)核緩沖區(qū)中。
  2. 直接緩沖區(qū)可以通過(guò)調(diào)用該緩沖區(qū)類(lèi)的allocateDirect(int capacity) 方法創(chuàng)建,此方法返回的緩沖區(qū)進(jìn)行分配和取消分配所需的成本要高于非直接緩沖區(qū)。直接緩沖區(qū)的內(nèi)容駐留在垃圾回收堆之外,因此他們對(duì)應(yīng)用程序內(nèi)存(JVM內(nèi)存)需求不大。所以建議直接緩沖區(qū)要分配給那些大型,持久(就是緩沖區(qū)的數(shù)據(jù)會(huì)被重復(fù)利用)的緩沖區(qū),一般情況下,最好僅在直接緩沖區(qū)能在程序性能帶來(lái)非常明顯的好處時(shí)才分配它們。
  3. 直接緩沖區(qū)還可以通過(guò)FileCHannel的map()方法將文件區(qū)域映射到內(nèi)存中來(lái)創(chuàng)建,該方法返回MappedByteBuffer。java平臺(tái)的實(shí)現(xiàn)有助于通過(guò)JNI本地代碼創(chuàng)建直接字節(jié)緩沖區(qū),如果以上這些緩沖區(qū)中某個(gè)緩沖區(qū)實(shí)例指向的是不可訪問(wèn)的內(nèi)存區(qū)域,則試圖方法該區(qū)域不會(huì)更改緩沖區(qū)的內(nèi)容,并且會(huì)在訪問(wèn)期間或者稍后的某個(gè)時(shí)間導(dǎo)致報(bào)出不確定性異常。
  4. 字節(jié)緩沖區(qū)是直接緩沖區(qū)還是非直接緩沖區(qū)可以通過(guò)調(diào)用其isDIrect()方法來(lái)判斷。

基于NIO的本地IO直接內(nèi)存使用:

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

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

  1. 應(yīng)用進(jìn)程發(fā)起一個(gè)讀請(qǐng)求系統(tǒng)調(diào)用,然后進(jìn)程切換到內(nèi)核態(tài)。
  2. DMA把磁盤(pán)數(shù)據(jù)復(fù)制到內(nèi)核緩沖區(qū)中。
  3. 內(nèi)核把緩沖區(qū)數(shù)據(jù)復(fù)制到用戶緩沖區(qū)中。
  4. 進(jìn)程切換到用戶態(tài)。
  5. 應(yīng)用進(jìn)程發(fā)起一個(gè)寫(xiě)請(qǐng)求系統(tǒng)調(diào)用,然后進(jìn)程切換到內(nèi)核態(tài)。
  6. 內(nèi)核把用戶緩沖區(qū)數(shù)據(jù)復(fù)制到內(nèi)核緩沖區(qū)。
  7. DMA把內(nèi)核緩沖區(qū)數(shù)據(jù)復(fù)制到磁盤(pán)上。
  8. 返回。

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

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

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

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

使用mmap后的IO大致流程:

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

相關(guān)API demo以及比較:詳細(xì)api解釋可以查看Java NIO學(xué)習(xí)篇之通道FileChannel詳解

//使用直接緩沖區(qū)API進(jìn)行一個(gè)700多M的文件進(jìn)行拷貝
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ū)耗時(shí):" + (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ū)耗時(shí):" + (System.currentTimeMillis()-start));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

執(zhí)行結(jié)果:

?

到此這篇關(guān)于淺析Java NIO 直接緩沖區(qū)和非直接緩沖區(qū)的文章就介紹到這了,更多相關(guān)Java NIO 直接緩沖區(qū)和非直接緩沖區(qū)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中四種訪問(wèn)權(quán)限資料整理

    Java中四種訪問(wèn)權(quán)限資料整理

    這篇文章主要介紹了 Java中四種訪問(wèn)權(quán)限總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java String創(chuàng)建對(duì)象實(shí)例解析

    Java String創(chuàng)建對(duì)象實(shí)例解析

    這篇文章主要介紹了Java String創(chuàng)建對(duì)象實(shí)例解析,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • MyEclipse設(shè)置Console輸出到文件的實(shí)現(xiàn)方法

    MyEclipse設(shè)置Console輸出到文件的實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇MyEclipse設(shè)置Console輸出到文件的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • Java Scala實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪查改操作詳解

    Java Scala實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪查改操作詳解

    這篇文章主要介紹了Java Scala實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪查改操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-04-04
  • Java中HashMap的初始容量設(shè)置方式

    Java中HashMap的初始容量設(shè)置方式

    這篇文章主要介紹了Java中HashMap的初始容量設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 9個(gè)小技巧讓你的Java if else看起來(lái)更優(yōu)雅

    9個(gè)小技巧讓你的Java if else看起來(lái)更優(yōu)雅

    這篇文章主要給大家介紹了9個(gè)小技巧,通過(guò)這幾個(gè)小技巧可以讓你的Java if else看起來(lái)更優(yōu)雅,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 簡(jiǎn)單了解java中靜態(tài)初始化塊的執(zhí)行順序

    簡(jiǎn)單了解java中靜態(tài)初始化塊的執(zhí)行順序

    這篇文章主要介紹了簡(jiǎn)單了解java中靜態(tài)初始化塊的執(zhí)行順序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • 如何通過(guò)自定義spring?invalidator注解校驗(yàn)數(shù)據(jù)合法性

    如何通過(guò)自定義spring?invalidator注解校驗(yàn)數(shù)據(jù)合法性

    這篇文章主要介紹了如何通過(guò)自定義spring?invalidator注解校驗(yàn)數(shù)據(jù)合法性,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • java 中的亂碼問(wèn)題匯總及解決方案

    java 中的亂碼問(wèn)題匯總及解決方案

    這篇文章主要介紹了java 中的亂碼問(wèn)題匯總相關(guān)資料,并附解決方案,出現(xiàn)亂碼問(wèn)題有編碼與解碼,字節(jié)流與字符流出現(xiàn)亂碼,等其他情況,需要的朋友可以參考下
    2016-11-11
  • Mybatis-Plus3.2.0 MetaObjectHandler 無(wú)法進(jìn)行公共字段全局填充

    Mybatis-Plus3.2.0 MetaObjectHandler 無(wú)法進(jìn)行公共字段全局填充

    這篇文章主要介紹了Mybatis-Plus3.2.0 MetaObjectHandler 無(wú)法進(jìn)行公共字段全局填充,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11

最新評(píng)論