最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

定義

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

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

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

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

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

  1. 應(yīng)用進(jìn)程發(fā)起一個讀請求系統(tǒng)調(diào)用,然后進(jìn)程切換到內(nèi)核態(tài)。
  2. DMA把磁盤數(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ā)起一個寫請求系統(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ù)制到磁盤上。
  8. 返回。

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

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

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

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

使用mmap后的IO大致流程:

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

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

//使用直接緩沖區(qū)API進(jìn)行一個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ū)耗時:" + (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í)行結(jié)果:

?

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

相關(guān)文章

  • Shiro安全框架的主要組件及認(rèn)證過程簡介

    Shiro安全框架的主要組件及認(rèn)證過程簡介

    這篇文章主要介紹了Shiro安全框架的主要組件及認(rèn)證過程簡介,Shiro?是一個強(qiáng)大靈活的開源安全框架,可以完全處理身份驗(yàn)證、授權(quán)、加密和會話管理,本文就來介紹一下此框架的核心組成,需要的朋友可以參考下
    2023-08-08
  • SpringSecurity+JWT實(shí)現(xiàn)前后端分離的使用詳解

    SpringSecurity+JWT實(shí)現(xiàn)前后端分離的使用詳解

    這篇文章主要介紹了SpringSecurity+JWT實(shí)現(xiàn)前后端分離的使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java 測試URL地址是否能正常連接的代碼

    Java 測試URL地址是否能正常連接的代碼

    本文給大家分享兩段代碼分別是java測試URL地址是否能正常連接和Java檢測URL是否可用或者可打開的代碼,代碼都很簡單,有需要的朋友可以參考下
    2016-08-08
  • springboot如何獲取相對路徑文件夾下靜態(tài)資源的方法

    springboot如何獲取相對路徑文件夾下靜態(tài)資源的方法

    這篇文章主要介紹了springboot如何獲取相對路徑文件夾下靜態(tài)資源的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • Java Spring Boot消息服務(wù)萬字詳解分析

    Java Spring Boot消息服務(wù)萬字詳解分析

    在實(shí)際項(xiàng)目開發(fā)中,有時需要與其他系統(tǒng)進(jìn)行集成完成相關(guān)業(yè)務(wù)功能,這種情況最原始做法是程序內(nèi)部相互調(diào)用,除此之外,還可以用消息服務(wù)中間件進(jìn)行業(yè)務(wù)處理,用消息服務(wù)中間件處理業(yè)務(wù)能夠提升系統(tǒng)的異步通信和擴(kuò)展解耦能力。Spring Boot對消息服務(wù)管理提供了非常好的支持
    2021-10-10
  • 解決Java字符串JSON轉(zhuǎn)換異常:cn.hutool.json.JSONException:?Mismatched?hr?and?body

    解決Java字符串JSON轉(zhuǎn)換異常:cn.hutool.json.JSONException:?Mismatched?

    這篇文章主要給大家介紹了關(guān)于如何解決Java字符串JSON轉(zhuǎn)換異常:cn.hutool.json.JSONException:?Mismatched?hr?and?body的相關(guān)資料,文中將解決的辦法通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • SpringSecurity+jwt+redis基于數(shù)據(jù)庫登錄認(rèn)證的實(shí)現(xiàn)

    SpringSecurity+jwt+redis基于數(shù)據(jù)庫登錄認(rèn)證的實(shí)現(xiàn)

    本文主要介紹了SpringSecurity+jwt+redis基于數(shù)據(jù)庫登錄認(rèn)證的實(shí)現(xiàn),其中也涉及到自定義的過濾器和處理器,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • Spring?Boot在啟動時執(zhí)行一次的功能實(shí)現(xiàn)

    Spring?Boot在啟動時執(zhí)行一次的功能實(shí)現(xiàn)

    這篇文章主要給大家介紹了關(guān)于Spring?Boot在啟動時執(zhí)行一次的功能實(shí)現(xiàn),在實(shí)習(xí)過程中,有時候會遇到一些項(xiàng)目啟動初始化的需求,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • SpringBoot+LayIM+t-io 實(shí)現(xiàn)好友申請通知流程

    SpringBoot+LayIM+t-io 實(shí)現(xiàn)好友申請通知流程

    這篇文章主要介紹了 SpringBoot+LayIM+t-io 實(shí)現(xiàn)好友申請通知流程,本文圖文并茂給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2017-12-12
  • springboot集成redis啟動報(bào)錯問題的解決方式

    springboot集成redis啟動報(bào)錯問題的解決方式

    這篇文章主要介紹了springboot集成redis啟動報(bào)錯問題的解決方式,從錯誤信息上看缺少pool2相關(guān)包,查詢資料發(fā)現(xiàn)當(dāng)redis客戶端選擇Lettuce時候需要增加:commons-pool2
    添加引用,重啟服務(wù),需要的朋友可以參考下
    2023-11-11

最新評論

包头市| 万源市| 临汾市| 天台县| 巴林右旗| 东辽县| 古浪县| 德化县| 门源| 济宁市| 乌兰县| 垣曲县| 兰溪市| 高唐县| 县级市| 山阴县| 肥西县| 闽清县| 竹溪县| 广东省| 洪湖市| 河北区| 和田市| 洛隆县| 花垣县| 沂源县| 静乐县| 平顶山市| 蕲春县| 昌邑市| 日土县| 嘉鱼县| 塔城市| 广元市| 桦川县| 白沙| 同仁县| 电白县| 神木县| 奉新县| 裕民县|