IO底层—数据拷⻉细节

思考

1.Linux读写文件会涉及几次上下文切换和数据拷贝?

2.用户态和内核态怎么理解?

3.page Cache属于哪一层缓存?

4.BufferedInputStream是减少哪一层耗时?

5.为什么需要这么多层缓存?

传统的IO拷贝过程


传统的IO拷贝过程,涉及用户态,内核态,磁盘。上图表示读写磁盘的过程图,数据需要从用户态拷贝到内核态再拷贝到磁盘,磁盘的数据也需要先到内核态再到用户态。这就需要了4次拷贝,从用户态切换到内核态,需要进行一次上下文切换,从内核态切换到用户态也需要进行一次上下文切换,如上图所示,需要4次上下文切换。

其它拷贝方式


如上图所示,application在用户态,page cache在内核态,mmap直接把Page Cache映射到了用户态的地址空间里了,所以mmap的方式从磁盘读文件是没有内核态到用户态的拷贝过程的。Direct IO则直接让用户态和块IO层对接,直接放弃Page Cache,从磁盘直接和用户态拷贝数据。
这两种方案,在写或第一次读的时候会比较快一点。至于第二次读呢,当然是拷贝到了最近的用户态会比较快一点。因为缓存的地方最近。

用户态和内核态怎么理解

cpu运行用户代码,就说cpu运行在用户态;cpu运行操作系统代码,cpu就运行在内核态;比如java的读磁盘IO,就要把文件从磁盘拷贝到操作系统内存(pagecache,这个时候cpu运行在内核态),然后再拷贝到jvm的内存(其实就是你程序里面用的字节数组接收),这个时候cpu是运行在用户态,所以叫做用户态内存。

BufferedInputStream是减少哪一层耗时

那这样看来,我们在调用java api操作io接口时,用到的缓存比如BufferedInputStream是为了减少哪一层呢,
其实减少的就是用户态到内核态的系统调用次数。

为什么需要这么多层缓存

其实这些用户态内存和内核态内存都处于虚拟空间中,都是对物理地址的映射,详细可以了解下虚拟内存,之所以这样分,我想主要是操作系统需要封装对磁盘的一些调用,这个调用是比较慢的,所以需要缓存;而我们的进程又是对操作系统的调用,所以数据缓存到离读取的地方越近越好。

参考链接:

从内核文件系统看文件读写过程

关于Linux的零拷贝技术详解

浅析Linux IO,你需要知道的底层

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 基础知识 1.1、 基本概念、 功能 冯诺伊曼体系结构1、计算机处理的数据和指令一律用二进制数表示2、顺序执...
    yunpiao阅读 5,440评论 1 22
  • 转自JAVA IO 以及 NIO 理解 一段话总结:传统io中从磁盘中中读文件,并把文件通过网络(socket)发...
    抓兔子的猫阅读 1,382评论 0 4
  • 由于Netty,了解了一些异步IO的知识,JAVA里面NIO就是原来的IO的一个补充,本文主要记录下在JAVA中I...
    骚的掉渣阅读 705评论 0 8
  • 上一篇《聊聊同步、异步、阻塞与非阻塞》已经通俗的讲解了,要理解同步、异步、阻塞与非阻塞重要的两个概念点了,没有看过...
    天草二十六_简村人阅读 802评论 0 4
  • 必备的理论基础 1.操作系统作用: 隐藏丑陋复杂的硬件接口,提供良好的抽象接口。 管理调度进程,并将多个进程对硬件...
    drfung阅读 3,595评论 0 5