美文网首页
Java NIO之基础知识篇

Java NIO之基础知识篇

作者: 文武文武 | 来源:发表于2017-07-02 15:17 被阅读0次

缓冲区操作

    进程执行I/O操作,归结起来,也就是向操作系统发出请求,让它要么把缓冲区里的数据排干(写),要么用数据把缓冲区填满(读)。进程使用这一机制处理所有数据进出操作。

I/O缓冲区操作简图

进程使用read()系统调用,要求其缓冲区被填满。内核随即向磁盘控制硬件发出命令,要求其从磁盘读取数据。磁盘控制器把数据直接写入内核内存缓冲区,这一步通过DMA完成,无需主CPU协助。一旦磁盘控制器把缓冲区装满,内核即把数据从内核空间的临时缓冲区拷贝到进程执行read()调用时指定的缓冲区。

用户空间:常规进程所在区域。JVM就是常规进程,驻守于用户空间。用户空间是非特权区域。

内核空间:操作系统所在区域。内核代码有特别的权力:它能与设备控制器通讯,控制着用户区域进程的运行状态,等等。最重要的是,所有I/O都直接或间接通过内核空间。

当进程请求I/O操作的时候,它执行一个系统调用将控制权交给内核。当内核以这种方式被调用时,它随即采取任何必要步骤,找到进程所需数据,并把数据传送到用户空间的指定缓冲区。内核试图对数据进行高速缓存或预读取,因此进程所需数据可能已经在内核空间里了。如果是这样,该数据只要简单的拷贝出来即可。如果数据不再内存空间,则进程被挂起,内核着手把数据读进内存。

为什么不直接让磁盘控制器把数据送到用户空间的缓冲区?

1.硬件通常不能直接访问用户空间

2.磁盘基于块存储操作的是固定大小的数据块,而用户进程请求的可能是任意大小的或非对齐的数据块。在数据往来于用户空间与存储设备的过程中,内核负责数据的分解、再组合工作,充当着中间人的角色。

发散/汇聚

根据发散/汇聚的概念,进程只需一个系统调用,就能把一连串缓冲区地址传递给操作系统。然后内核就可以顺序填充或排干多个缓冲区,读的时候就把数据发散到多个用户空间缓冲区,写的时候再从多个缓冲区把数据汇聚起来。

三个缓冲区的发散读操作

这样用户进程就不必多次执行系统调用,内核也可以优化数据的处理过程,因为它已掌握待传输数据的全部信息。如果系统配有多个CPU,甚至可以同时填充或排干多个缓冲区。

虚拟内存

    使用虚拟地址取代物理内存地址。

    好处:

        1.一个以上的虚拟地址可指向同一个物理内存地址。

        2.虚拟内存空间可大于实际可用的硬件内存。

把内核空间地址与用户空间的虚拟地址映射到同一物理地址,这样,DMA硬件(只能访问物理内存地址)就可以填充对内核与用户空间进程同时可见的缓冲区。

内存空间多重映射

省去了内核与用户空间的往来拷贝。

前提条件:内核与用户缓冲区必须使用相同的页对齐,缓冲区的大小还必须是磁盘控制器块大小的倍数

内存页

上图显示了多个虚拟地址的虚拟内存页是如何映射到物理内存的。

内存页面调度

为了支持虚拟内存寻址空间大于物理内存的特性,就必须进行内存分页。虚拟内存空间的页面能够继续存在于外部磁盘存储,这样就为物理内存中的其它虚拟页面腾出了空间。从本质上来说,物理内存充当了分页区的高速缓存,而所谓的分页区,即从物理内存置换出来,转而存储于磁盘上的内存页面。

用于分页区高速缓存的物理内存

上图显示了分属于四个进程的虚拟页面,其中每个进程都有属于自己的虚拟内存空间,进程A有五个页面,其中两个装入内存,其余存储于磁盘。

现代CPU包含一个称为内存管理单元(MMU)的子系统,该设备包含虚拟地址向物理内存地址转换时所需映射信息。当CPU引用某内存地址时,MMU负责确定该地址所在页,并将虚拟页号转换为物理页号(这一步由硬件完成,速度极快)。如果当前不存在与虚拟页形成有效映射的物理内存页,MMU会向CPU提交一个页错误。然后把控制权交给内核,由内核主导从磁盘上将该页读入物理内存,更新MMU。

文件I/O

文件I/O属文件系统范畴,文件系统与磁盘迥然不同。磁盘属于存储的硬件设备,文件系统是更高层次的抽象,是安排、解释磁盘数据的一种独特方式。

文件系统把一连串大小一致的数据块组织到一起。当用户进程请求读取文件数据时,文件系统需要确定数据具体在磁盘什么位置,然后着手把相关磁盘扇区读进内存。

操作系统还有页的概念,其大小或者与基本内存页一致,或者是其倍数。典型的操作系统页从2048到8192字节不等,且始终是基本内存页大小的倍数。

采用分页技术的操作系统执行I/O的全过程可总结为以下几步:

1.确定请求的数据分布在文件系统的哪些页。

2.在内核空间分配足够数量的内存页,以容纳得到确定的文件系统页。

3.在内存页与磁盘上的文件系统页之间建立映射。

4.为每一个内存页产生错误。

5.虚拟内存系统俘获页错误,安排页面调入,从磁盘上读取页内容,使页有效。

6.一旦页面调入操作完成,文件系统即对原始数据进行解析,取得所需文件内容或属性信息。

内存映射文件

用户内存到文件系统页的映射

内存映射I/O使用文件系统建立从用户空间直到可用文件系统页的虚拟内存映射。好处如下:

1.用户进程把文件数据当成内存,所以无需发布read()或write()系统调用。

2.当用户进程碰触到映射内存空间,页错误会自动产生从而将文件数据从磁盘读进内存。如果用户修改了内存映射空间,相关页会自动标记为脏随后刷新到磁盘,文件得到更新。

3.操作系统的虚拟内存子系统会对页进行智能高速缓存,自动根据系统负载进行内存管理。

4.数据总是按页对齐,无需执行缓冲区拷贝。

5.大型文件使用映射,无需耗费大量内存即可进行数据拷贝。

流I/O

流的传输一般比块设备慢,经常用于间歇性输入。多数操作系统允许把流置于非块模式,这样,进程可以查看流上是否有输入,即便当时没有也不影响它干别的。这样一种能力使得进程可以在有输入的时候进行处理,输入闲置的时候执行其他功能。。

相关文章

网友评论

      本文标题:Java NIO之基础知识篇

      本文链接:https://www.haomeiwen.com/subject/hofpcxtx.html