Netty的深入浅出--36.再次深入零拷贝剖析
传统IO通信:当我们通过read() syscall进行系统调用的使用,会出现一次空间切换,从用户空间切换都了内核空间。紧接着就是从内核空间读取硬盘上的数据保存到内核缓存中。然后将从内核缓存中将数据拷贝到用户缓存中。这个时候又出现了空间切换,内核空间向用户空间切换。当代码逻辑结束之后,又该数据拷贝回内核空间,这里有进行一次空间切换。后面我就不分析了,总体来说,传统IO通信导致出现了多次的数据拷贝以及空间切换
这里我对空间切换的理解:比如说用户空间就好比java虚拟机平台,内核空间好比操作系统平台,而java 虚拟机又是在操作系统之上的,当有些方法需要调用本地方法的时候,这样时候需要从虚拟机切换到操作系统,这个就称之为空间切换(这只是基于本人个人理解,有不对的地方,请留言指正,谢谢)
因此还是得 使用NIO:
这样的话,数据拷贝以及操作都放到了内核空间上,减少了用户切换,但是问题还是存在的,那就是数据的拷贝还是很多。
最终改进的零拷贝方案
数据从磁盘拷贝到内核缓存区中之后,不会像之前那样拷贝一份到socket buffer里面。而是将文件数据内存地址和文件数据读取长度拷贝到socket buffer中 ,这样的话,拷贝到socket buffer里面的数据就少了很多很多。相当于scatter
而protocol engine通过两个buffer来获取最终的数据相当于gather,然后将数据发送给服务器端。