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

Java圖文并茂詳解NIO與零拷貝

 更新時(shí)間:2022年11月11日 09:49:07   作者:頑石九變  
零拷貝是網(wǎng)絡(luò)編程的關(guān)鍵,很多性能優(yōu)化都離不開。在?Java?程序中,常用的零拷貝有?mmap(memory?map,內(nèi)存映射)?和?sendFile。那么它們?cè)?OS(操作系統(tǒng))?中,到底是怎么樣的一個(gè)的設(shè)計(jì)?另外我們看下NIO?中如何使用零拷貝

零拷貝指的是沒有CPU拷貝,并不是不拷貝;減少上下文切換

一、概念說明

1、傳統(tǒng)IO

需要4次拷貝,3次上下文切換

2、mmap

mmap 通過內(nèi)存映射,將文件映射到內(nèi)存緩沖區(qū),同時(shí)用戶空間可以共享內(nèi)存緩沖區(qū)的數(shù)據(jù),減少內(nèi)核空間到用戶空間的拷貝

需要3次拷貝,3次上下文切換

3、sendfile

Linux 2.4 避免了從內(nèi)核緩沖區(qū)到Socket Buffer的拷貝,直接拷貝到協(xié)議棧,從而減少一次數(shù)據(jù)拷貝

需要2次拷貝,3次上下文切換

4、mmap與sendfile

mmap適合小數(shù)據(jù)量讀寫,sendfile適合大文件傳輸

mmap需要4次上下文切換,3次數(shù)據(jù)拷貝;sendfile需要3次上下文切換,最少2次數(shù)據(jù)拷貝

send可用利用DMA方式,減少CPU拷貝,mmap則不能(必須從內(nèi)核拷貝到Socket緩沖區(qū))

二、傳統(tǒng)IO傳輸文件代碼示例

1、服務(wù)端代碼

import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class BIOServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(7000);
        while (true) {
            Socket socket = serverSocket.accept();
            DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
            try {
                long total = 0;
                byte[] bytes = new byte[4096];
                FileOutputStream fileOutputStream = new FileOutputStream("d:\\temp\\04.zip");
                while (true) {
                    int read = dataInputStream.read(bytes, 0, bytes.length);
                    if (read == -1) {
                        //文件讀取結(jié)束,退出循環(huán)
                        break;
                    }
                    total += read;
                    fileOutputStream.write(bytes, 0, read);
                }
                System.out.println("收到客戶端發(fā)送文件,總字節(jié)數(shù):" + total);
                fileOutputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

2、客戶端代碼

import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
public class BIOClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 7000);
        FileInputStream fileInputStream = new FileInputStream("d:\\temp\\03.zip");
        DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
        byte[] bytes = new byte[4096];
        long readCount;
        long total = 0;
        long start = System.currentTimeMillis();
        while ((readCount = fileInputStream.read(bytes)) >= 0) {
            total += readCount;
            dataOutputStream.write(bytes);
        }
        System.out.println("發(fā)送總字節(jié)數(shù):" + total + ", 總耗時(shí):" + (System.currentTimeMillis() - start));
        dataOutputStream.close();
        socket.close();
        fileInputStream.close();
    }
}

3、控制臺(tái)出輸出

測(cè)試發(fā)送9M的壓縮文件,耗時(shí)在26ms左右

發(fā)送總字節(jié)數(shù):9428963, 總耗時(shí):26

三、NIO傳輸文件代碼示例

1、服務(wù)端代碼

package com.hj.io.nio.zero;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class NIOServerFile {
    public static void main(String[] args) throws IOException {
        InetSocketAddress address = new InetSocketAddress(7000);
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(address);
        //創(chuàng)建buffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
        while (true) {
            //等待客戶端鏈接
            SocketChannel socketChannel = serverSocketChannel.accept();
            System.out.println("收到客戶端鏈接");
            int total = 0;
            FileOutputStream fileOutputStream = new FileOutputStream("d:\\temp\\05.zip");
            //循環(huán)讀取數(shù)據(jù),并存儲(chǔ)到硬盤
            while (true) {
                try {
                    int readCount = socketChannel.read(byteBuffer);
                    if (readCount == -1) {
                        //文件讀取結(jié)束
                        break;
                    }
                    total += readCount;
                    fileOutputStream.write(byteBuffer.array(),0,readCount);
                    //將buffer倒帶
                    byteBuffer.rewind();
                } catch (IOException e) {
                   break;
                }
            }
            System.out.println("收到客戶端發(fā)送文件,總字節(jié)數(shù):" + total);
            fileOutputStream.close();
        }
    }
}

2、客戶端代碼

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
public class NIOClientFile {
    public static void main(String[] args) throws IOException {
        //打開一個(gè)SocketChannel并鏈接到服務(wù)器端
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 7000));
        //打開一個(gè)文件
        FileChannel fileChannel = new FileInputStream("d:\\temp\\03.zip").getChannel();
        //發(fā)送文件到服務(wù)器
        long start = System.currentTimeMillis();
        //在linux下,一次transferTo調(diào)用就可以完成傳輸
        //在windows下,一次transferTo調(diào)用最多只能傳8M,大文件需要分段傳輸,需要注意傳輸位置
        //transferTo底層使用零拷貝
        long total = fileChannel.size();
        long sended = 0;
        while (sended < total) {
            //從上一次傳輸位置繼續(xù)發(fā)送
            long lenth = fileChannel.transferTo(sended, fileChannel.size(), socketChannel);
            sended += lenth;
        }
        System.out.println("發(fā)送總字節(jié)數(shù):" + sended + ",總耗時(shí):" + (System.currentTimeMillis() - start));
        //關(guān)閉channel
        fileChannel.close();
        socketChannel.close();
    }
}

3、控制臺(tái)出輸出

測(cè)試發(fā)送9M的壓縮文件,耗時(shí)在16ms左右

發(fā)送總字節(jié)數(shù):9428963,總耗時(shí):16

四、總結(jié)

使用零拷貝傳輸,性能明顯高于傳統(tǒng)IO傳輸

到此這篇關(guān)于Java圖文并茂詳解NIO與零拷貝的文章就介紹到這了,更多相關(guān)Java NIO與零拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)ip地址和int數(shù)字的相互轉(zhuǎn)換

    Java實(shí)現(xiàn)ip地址和int數(shù)字的相互轉(zhuǎn)換

    這篇文章主要介紹了Java實(shí)現(xiàn)ip地址和int數(shù)字的相互轉(zhuǎn)換,幫助大家更好的利用Java處理數(shù)據(jù),感興趣的朋友可以了解下
    2020-09-09
  • Spring中SmartLifecycle的用法解讀

    Spring中SmartLifecycle的用法解讀

    這篇文章主要介紹了Spring中SmartLifecycle的用法解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Eclipse?2022?設(shè)置中文漢化的超詳細(xì)圖文教程

    Eclipse?2022?設(shè)置中文漢化的超詳細(xì)圖文教程

    這篇文章主要介紹了Eclipse?2022?設(shè)置中文漢化的超詳細(xì)圖文教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Java設(shè)計(jì)模式之代理模式(Proxy模式)介紹

    Java設(shè)計(jì)模式之代理模式(Proxy模式)介紹

    這篇文章主要介紹了Java設(shè)計(jì)模式之代理模式(Proxy模式)介紹,本文講解了為什么要使用代理模式、如何使用代理模式等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • Java文件讀寫IO/NIO及性能比較詳細(xì)代碼及總結(jié)

    Java文件讀寫IO/NIO及性能比較詳細(xì)代碼及總結(jié)

    這篇文章主要介紹了Java文件讀寫IO/NIO及性能比較詳細(xì)代碼及總結(jié),具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java中常用的9種文件下載方法總結(jié)

    Java中常用的9種文件下載方法總結(jié)

    下載文件在我們項(xiàng)目很常見,有下載視頻、文件、圖片、附件、導(dǎo)出Excel等,所以本文為大家整理了9中Java中常用的文件下載方式,希望對(duì)大家有所幫助
    2023-09-09
  • Java正則表達(dá)式API Matcher類方法

    Java正則表達(dá)式API Matcher類方法

    這篇文章主要介紹了Java正則表達(dá)式API Matcher類方法,對(duì)Matcher類的一些有用方法進(jìn)行功能對(duì)它們進(jìn)行分組展開介紹,需要的朋友可以參考一下
    2022-06-06
  • Java泛型T,E,K,V,N,?與Object區(qū)別和含義

    Java泛型T,E,K,V,N,?與Object區(qū)別和含義

    Java?泛型(generics)是?JDK?5?中引入的一個(gè)新特性,?泛型提供了編譯時(shí)類型安全檢測(cè)機(jī)制,該機(jī)制允許程序員在編譯時(shí)檢測(cè)到非法的類型。本文將詳細(xì)講講Java泛型T、E、K、V、N、?和Object區(qū)別和含義,需要發(fā)可以參考一下
    2022-03-03
  • IDEA中實(shí)現(xiàn)springboot熱部署方式

    IDEA中實(shí)現(xiàn)springboot熱部署方式

    在IDEA中實(shí)現(xiàn)SpringBoot的熱部署可以通過修改設(shè)置來完成,首先在設(shè)置中搜索Compiler,并勾選Build project automatically,然后進(jìn)入Advanced Settings,勾選Allow auto-make to start even if developed application is currently running
    2024-09-09
  • JAVA偏向鎖的原理與實(shí)戰(zhàn)

    JAVA偏向鎖的原理與實(shí)戰(zhàn)

    這篇文章主要為大家詳細(xì)介紹了JAVA偏向鎖的原理與實(shí)戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03

最新評(píng)論

志丹县| 甘南县| 绥阳县| 伊吾县| 龙山县| 凯里市| 延长县| 南川市| 那曲县| 景泰县| 万全县| 固安县| 兴海县| 石泉县| 类乌齐县| 许昌县| 桂东县| 婺源县| 綦江县| 保靖县| 苏尼特右旗| 铜梁县| 阜新市| 泸西县| 舞阳县| 大兴区| 当雄县| 汪清县| 凯里市| 古交市| 文登市| 青海省| 太和县| 阿拉尔市| 昌图县| 乐山市| 龙海市| 郴州市| 措美县| 五大连池市| 新宾|