【netty学习】之零拷贝

零拷贝

1、零拷贝是从操作系统的角度出发,因为内核缓冲区之间没有数据是重复的,只有kernel buffer一份数据
2、零拷贝不仅仅带来更少的数据复制,还能带来其他性能的优势,例如更少的上下文切换,更少的cpu缓存伪共享,以及无cpu校验和计算

DMA(direct memory Access):直接存储器访问

mmap内存映射和sendFile的区别

1、mmap适合小数据量读写,sendfile适合大文件传输
2、mmap需要4次上下文切换,3次数据拷贝;sendFile需要3次上下文切换,最少2次数据拷贝
3、sendFile可以利用DMA方式,减少CPU拷贝,mmap则不能(必须从内核拷贝到socket缓冲区)

标题代码实例记录:

// server端
package com.example.demo.nio.ZeroCopy;

import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class NewIOSever {
    public static void main(String[] args) throws Exception{
        InetSocketAddress inetSocketAddress = new InetSocketAddress(7001);
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        ServerSocket serverSocket = serverSocketChannel.socket();
        //绑定端口
        serverSocket.bind(inetSocketAddress);

        //创建buffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        while (true){
            SocketChannel socketChannel = serverSocketChannel.accept();
            System.out.println("进来的连接:" + socketChannel.getRemoteAddress());
            int readCount = 0;
            while (-1 != readCount){
                try{
                    readCount = socketChannel.read(byteBuffer);
                }catch (Exception ex){
                    break;
                }

                //进行倒带
                byteBuffer.rewind();//position为0,mark作废
            }
        }
    }

}

客户端

//客户端
package com.example.demo.nio.ZeroCopy;

import java.io.FileInputStream;
import java.net.InetSocketAddress;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;

public class NewIOClient {
   public static void main(String[] args) throws Exception{
       SocketChannel socketChannel = SocketChannel.open();
       socketChannel.connect(new InetSocketAddress("127.0.0.1", 7001));
       String fileName = "interview.pdf";

       //得到一个文件channel
       FileChannel fileChannel = new FileInputStream(fileName).getChannel();
       System.out.println("socketChannel的地址:" + socketChannel.getLocalAddress());
       long startTime = System.currentTimeMillis();
       //在linux下调用transferTo方法可以完成传输,在windows下,一次只能传输8M文件
       //准备发送
       long transferCount = fileChannel.transferTo(0, fileChannel.size(), socketChannel);

       System.out.println("发送总字节数="+transferCount+",耗时:"+(System.currentTimeMillis()-startTime));
       fileChannel.close();
   }
}

总结:代码主要演示由netty提供的transferTo()方法可以直接进行零拷贝,与传统IO流复制文件相比确实速度提高很多
此处注意该方法调用时windows和linux系统存在差异

																										(画个太阳激励自己) ☀
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值