netty源码解读二(几种零拷贝的比较与堆外内存回收问题)

本文详细介绍了零拷贝的概念、产生背景及不同实现方式,包括mmap/write、sendfile和Linux内核的优化。讨论了Netty如何在Java中实现零拷贝,并探讨了堆外内存的分配、释放问题,特别是DirectByteBuffer的构造过程和Cleaner的作用。文章深入浅出地阐述了数据传输和内存管理在高性能网络编程中的重要性。
摘要由CSDN通过智能技术生成

零拷贝总览

1)传统IO 需要4次复制(包括两次cpu复制) 4次用户态内核态的切换;
2)mmap/write 需要3次复制(包括一次cpu复制) 4次用户态内核态的切换;
3)sendfile 需要3次复制(包括一次cpu复制) 2次用户态内核态的切换;
4)linux2.4优化后,2次(只有两次DMA复制),2次切换,没有了cpu拷贝,实现了真正的零拷贝;
零拷贝中的零指的是cpu的零拷贝,允许DMA拷贝;
零拷贝可以分为操作系统层面和java层面;上面四点就是操作系统层面,java层面的实现可以理解为传递的是引用或是位置信息,而不是直接复制;

零拷贝产生背景

cpu内部有高速缓存,寄存器,运行速度非常快,内存条速度次之,网卡再次之,硬盘速度最慢。

cpu将数据发送至网卡过程

现在用户控件有100kb数据需要发送到对端,过程是怎样的呢?当没有DMA时,cpu会先从内存条中读取100k数据至其高速缓存,接着cpu会将100k写至网卡,这么一来会使cpu速度会拉低到和网卡一个速度,因为在读写过程中,cpu没办法再去执行其他进程了,所以DMA应运而生。
首先cpu会将100k数据从内存条读到其高速缓存,然后写至socket写缓冲区(内核空间的一块缓冲区),这里有一次cpu复制,接着cpu通知DMA控制器,让其将100k数据由socket写缓冲区移到网卡中,DMA收到命令后,会读取socket写缓冲区的数据至其本地缓存中,接着DMA将数据写至网卡中,直到socket写缓冲区的数据读完,并且数据全部由DMA缓存写至网卡后,DMA会给cpu发送一条DMA中断,告知cpu我做完了。为啥会有中断呢,原因分析如下:
若socket写缓冲区为50k,cpu执行当前进程A,从内存条中读100K数据的一半至其高速缓存,再将这50k数据复制至socket写缓冲区,此时socket写缓冲区已满了,当前进程A会从cpu的运行队列中被移至socket写缓冲器的等待队列中,即进程A变成了阻塞状态,接着cpu通知DMA控制器,让其将50k数据由socket写缓冲区移到网卡中,DMA收到命令后,先会读取socket写缓冲区的50k数据至其缓存中,接着DMA将50k数据写至网卡中,接着DMA会给cpu发送一条DMA中断,cpu收到中断后,会立马中断掉当前正在执行的进程B,将其从用户态切换至内核态,执行中断处理程序,中断程序逻辑是将socket写缓冲区的等待队列中的进程A移至cpu的运行队列中,即进程A变成了运行状态,中断处理程序结束,cpu会继续执行,所以进程A再次获得运行权利,cpu再次执行当前进程A,从内存条中读剩下50k数据至其高速缓存,再将这50k数据复制至socket写缓冲区,即重复以上操作。

cpu从本地硬盘读取数据的过程

cpu首先检查内核文件缓冲区中是否有硬盘中的数据,若有,则直接读,若没有,cpu直接取读硬盘,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

orcharddd_real

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值