在全球范围内成功劫持28000台打印机
|
这一轮操作下来,我们数数经过了几次数据的拷贝?4 次。有 2 次是内核空间和用户空间之间的数据拷贝,这两次拷贝涉及到用户态和内核态的切换,需要CPU参与进来,进行上下文切换。而另外 2 次是硬盘和内核空间之间的数据拷贝,这个过程利用到 DMA与系统内存交换数据,不需要 CPU 的参与。 导致 IO 性能瓶颈的原因:内核空间与用户空间之间数据过多无意义的拷贝,以及多次上下文切换 操作状态用户进程请求读取数据用户态 -> 内核态操作系统内核返回数据给用户进程内核态 -> 用户态用户进程请求写数据到硬盘用户态 -> 内核态操作系统返回操作结果给用户进程内核态 -> 用户态
操作系统的零拷贝所以,操作系统出现了一个全新的概念,解决了 IO 瓶颈:零拷贝。零拷贝指的是内核空间与用户空间之间的零次拷贝。 零拷贝可以说是 IO 的一大救星,操作系统底层有许多种零拷贝机制,我这里仅针对 Java NIO 中使用到的其中一种零拷贝机制展开讲解。
在 Java NIO 中,零拷贝是通过用户空间和内核空间的缓冲区共享一块物理内存实现的,也就是说上面的图可以演变成这个样子。 有人会问,NIO 的文件拷贝和传统 IO 流的文件拷贝有何不同呢?我们在编程时感觉它们没有什么区别呀,貌似只是 API 不同罢了,我们接下来就去看看这两者之间的区别吧。 BIO 和 NIO 拷贝文件的区别这个时候就要来了解了解操作系统底层是怎么对 IO 和 NIO 进行区别的,我会用尽量通俗的文字带你理解,可能并不是那么严谨。 操作系统最重要的就是内核,它既可以访问受保护的内存,也可以访问底层硬件设备,所以为了保护内核的安全,操作系统将底层的虚拟空间分为了用户空间和内核空间,其中用户空间就是给用户进程使用的,内核空间就是专门给操作系统底层去使用的。 接下来,有一个 Java 进程希望把小菠萝这张图片从磁盘上拷贝,那么内核空间和用户空间都会有一个缓冲区
这张照片就会从磁盘中读出到内核缓冲区中保存,然后操作系统将内核缓冲区中的这张图片字节数据拷贝到用户进程的缓冲区中保存下来, 通道类都保存在 java.nio.channels 包下,我们日常用到的几个重要的类有 4 个:
可以通过 getChannel() 方法获取一个通道,支持获取通道的类如下:
示例:文件拷贝案例我们来看一个利用通道拷贝文件的例子,需要下面几个步骤:
这是一张小菠萝的照片,它存在于d:小菠萝文件夹下,我们将它拷贝到 d:小菠萝分身 文件夹下。 (编辑:衡水站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

