Java BIO与NIO的比较

前提:相对于传统IO,NIO将磁盘->内核空间缓冲区->用户空间缓冲区变为 

                                            磁盘->用户空间缓冲区  ,减少了中间的拷贝过程。

 

BIO读取过程:

读取过程(共三次复制拷贝过程):

1 jvm堆执行fileInputStream.read()请求操作系统,然后操作系统请求磁盘。

2 从磁盘中读取到数据,然后写到操作系统缓冲区中。

3 将数据从操作系统缓冲区放到jvm进程缓冲区(按字节流读取,即一个一个字节byte读取数据)。

4 jvm将jvm进程中缓冲区东西拷贝到jvm堆内存中(应用部署位置)。

Java BIO与NIO的比较

 

NIO读取过程:

与BIO的区别有如下两点:

1 相对于bio的一个一个byte传,nio是以channel形式读取buffer缓冲区,然后以块数据传输

Java BIO与NIO的比较

 

2 nio减少了复制过程(这里共两种方法)

第一种:jvm进程的虚拟地址空间直接从磁盘中读取。

直接把磁盘映射到JVM进程的虚拟地址空间,放置对应到页表上。

Java BIO与NIO的比较

上图可见BIO中2,3,4复制过程都没有了,变成如下:

-- 1 jvm堆执行fileInputStream.read()请求操作系统,然后操作系统请求磁盘。

-- 2 直接从磁盘映射到jvm进程的虚拟地址空间。

 

第二种:直接内存(堆外内存 DirectBuffer),删掉了BIO第4步的复制。

Java BIO与NIO的比较

 

3 采取多路复用技术监听请求

关键点如下:

1 只有一个线程用于监听

2 对应通道会注册感兴趣的事件(如读写事件)

3 假如通道注册了读事件,当通道发现有数据了,操作系统就会通知线程这个通道有数据了

4 这样的话,注册大量channel,都可以只要一个线程监听,只要事件触发了,操作系统就会通知该线程去处理。

5 这样当前线程会一直存在,避免上下文切换,该线程数据就能一直缓存在L1,L2,L3缓存当中(L1 L2 L3缓存讲解连接:https://baijiahao.baidu.com/s?id=1598811284058671259&wfr=spider&for=pc),页表也不需要重新刷新(描述逻辑页和物理页帧映射关系)。

 

 

参考文章:

https://www.cnblogs.com/dolphin0520/p/3920373.htmlhttps://www.cnblogs.com/dolphin0520/p/3920373.html

参考自Q群:Java交流讨论一群(250431014)-群主的帮助