零拷贝实现原理

[TOC]

内容拷贝过程

场景:从一个文件中读出并将数据传到另一台服务器
实现伪代码如下:

File.read(file, buf, len);
Socket.send(socket, buf, len);
// 此过程涉及4次拷贝
image

注意: 在应用拷贝时会涉及到用户态切换到内核态

  1. 应用程序调用read()方法,此处会设计到上下文切换(用户态->内核态),底层采用DMA(direct memory access)读取磁盘的文件,然后将内容存储到内核地址空间的读取缓冲区

  2. 应用程序无法读取内核地址空间的数据,这时read()调用返回,将内容从读取缓冲区拷贝到用户缓冲区,上下文切换(内核态 ->用户态),此时应用程序可以修改这些内容

  3. 通过Socket传到另一个服务中,调用Socket的send() 方法传到另一个服务中,然后再次将内容拷贝到内核地址空间缓冲区,此时又是一次上下文切换与目标套接字直接相连,与读取缓冲区无关

  4. send()调用返回,第四次数据拷贝,通过DMA(direct memory access)把数据从目标套接字相关的缓存区传到协议引擎进行发送

NIO优化

 在整个过程中,过程1和4是由DMA负责(类似通道Channel),并不会消耗CPU,只有过程2和3的拷贝需要CPU参与,可以直接把内核态读取缓冲区直接拷贝到套接字相关的缓冲区,优化如下图

image

实现方式:
FileChannel的 tansferTo() 方法可是实现,将数据从文件通道传输到给定的可写字节的通道,替换file.read() 方法和 socket.send()方法

//获取缓冲区
Buffer buffer=ByteBuffer.allocateDirect(1024);
//获取文件通道
FileChannel fileChannel = 
FileChannel.open(Paths.get(System.getProperty("user.dir")+ "/assets/file.txt"), StandardOpenOption.READ);
//获取socket通道
SocketChannel socketChannel=SocketChannel.open();
//将文件通道转到socket通道
fileChannel.transferTo(buffer.position(),buffer.limit(),socketChannel);

经过上述优化后后

  • 上下文切换的次数从四次减少到了两次
  • 数据拷贝次数从四次减少到了三次(其中DMA copy 2次,CPU copy 1次)

零拷贝的实现

Linux内核2.4及后期版本中,针对套接字缓冲区描述符做了调整,DMA自带了收集功能,内部操作发生了改变,用户使用不变,内部操作如下图:

image

遗留问题:

  1. 套接字缓冲区实现机制原理
  2. 文件描述符的实现原理

参考资料://www.greatytc.com/p/2581342317ce

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355