NIO与传统I/O之间I/O的区别

要想讲清楚nio的原理和它的优点得先清楚Java应用程序的文件读写原理和虚拟内存的原理。Java文件读取原理可参见如下图:

NIO与传统I/O之间I/O的区别

当应用程序需要读取文件的时候,内核首先通过DMA技术将文件内容从磁盘读入内核中的buffer,然后Java应用进程再从内核的buffer将数据读取到应用程序的buffer。

为了提升I/O效率和处理能力,操作系统采用虚拟内存的机制。虚拟内存也就是我们常说的交换内存,它实际上是硬盘上的文件,虚拟内存有两个作用:

1. 不同的虚拟内存可以映射到相同的物理内存,根据这个原理,可以简化文件读取流程,提升读取效率,效果如下图所示:

通过使用虚拟内存技术,将应用程序的buffer和内核的buffer都作为虚拟内存,并且两块不同的虚拟内存指向相同的物理内存内核通过DMA将数据读取到buffer的时候,应用程序就可以直接使用这些数据了。

2. 通过使用虚拟内存, 应用程序可以使用比物理内存所能容纳得大得多的内存,并且也能够提高I/O效率。当物理内存中的数据不使用的时候,可以将物理内存中的数据放到虚拟内存中,操作系统就可以腾出物理内存空间存储新的要处理的数据。当需要使用虚拟内存中的数据时,再可以把虚拟内存中的数据加载到物理内存中。因此物理内存可以看做时虚拟内存中存放数据的cache。而上面所述的cache虚拟内存数据的过程,对应用程序来说时透明的,它可以像处理物理内存数据一样处理虚拟内存中的数据。

Java nio通过使用虚拟内存技术将文件系统中的文件页和应用程序空间直接对应起来,使用nio后,文件的读写操作都是在虚拟内存中实现。这样在操作文件的时候,好像文件已经在内存中一样。采用了虚拟内存技术,使用Java nio方式可以很快的读取很大的文件。

通过把内核空间和用户空间的虚拟的地址映射到同一块物理地址,这样DMA硬件可以填充对内核空间和用户空间同时可见的缓冲区。

NIO与传统I/O之间I/O的区别