零拷贝(Zero-copy)学习


title: 零拷贝(Zero-copy)学习
categories: IO
tags: 零拷贝


概念

零拷贝(Zero-copy)是一种高效的数据传输机制,是指计算机执行操作时,CPU不需要先将数据从某处内存复制到另一个特定区域

传统IO传输方法
    public static void main(String[] args) throws IOException {
        File file = new File("test.txt");
        RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
        byte[] arr = new byte[(int) file.length()];
        accessFile.read(arr);
        Socket socket = new ServerSocket(6666).accept();
        socket.getOutputStream().write(arr);
    }

从操作系统层面来看这一次传输操作

1.JVM向OS发出read()系统调用,触发上下文切换,从用户态切换到内核态。

2.从外部存储(如硬盘)读取文件内容,通过直接内存访问(DMA)存入内核地址空间的缓冲区。

3.将数据从内核缓冲区拷贝到用户空间缓冲区,read()系统调用返回,并从内核态切换回用户态。

4.JVM向OS发出write()系统调用,触发上下文切换,从用户态切换到内核态。

5.将数据从用户缓冲区拷贝到内核中与目的地Socket关联的缓冲区。

6.数据最终经由Socket通过DMA传送到硬件(如网卡)缓冲区,write()系统调用返回,并从内核态切换回用户态。

img

上面总共是经过了4次上下文切换(严格来讲是模式切换),并且数据也被来回拷贝了4次

第2、3次拷贝(也就是从内核空间到用户空间的来回复制)是没有意义的,数据应该可以直接从内核缓冲区直接送入Socket缓冲区。零拷贝机制就实现了这一点。不过零拷贝需要由操作系统直接支持,不同OS有不同的实现方法

零拷贝

下面的零拷贝机制下的时序图。

零拷贝消除了从内核空间到用户空间的来回复制,因此“zero-copy”这个词实际上是站在内核的角度来说的,并不是完全不会发生任何拷贝。

img

在Java NIO包中提供了零拷贝机制对应的API,即FileChannel.transferTo()方法,可将拷贝次数变为3次,上下文切换次数减少到2次。

Scatter/Gather的优化

​ 从“Read buffer”到“Socket buffer”,在一般的Block DMA方式中,源物理地址和目标物理地址都得是连续的,所以一次只能传输物理上连续的一块数据,每传输一个块发起一次中断,直到传输完成,所以必须要在两个缓冲区之间拷贝数据。

而Scatter/Gather DMA方式则不同,会预先维护一个物理上不连续的块描述符的链表,描述符中包含有数据的起始地址和长度。传输时只需要遍历链表,按序传输数据,全部完成后发起一次中断即可,效率比Block DMA要高。也就是说,硬件可以通过Scatter/Gather DMA直接从内核缓冲区中取得全部数据,不需要再从内核缓冲区向Socket缓冲区拷贝数据。

对内存映射(mmap)的支持

以上机制,如果想在传输时修改数据本身,就无能为力了,不过,很多操作系统也提供了内存映射机制,对应的系统调用为mmap()/munmap()。通过它可以将文件数据映射到内核地址空间,直接进行操作

但是呢,这样会造成4次上下文切换,另外,它需要在快表(TLB)中始终维护着所有数据对应的地址空间,直到刷写完成,因此处理缺页的overhead也会更大。在使用该机制时,需要权衡效率。

NIO框架中提供了MappedByteBuffer用来支持mmap。它与常用的DirectByteBuffer一样,都是在堆外内存分配空间。相对地,HeapByteBuffer在堆内内存分配空间。

参考:https://www.jianshu.com/p/193cae9cbf07

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值