Java的缓冲流内部实现及其效率探讨

   对Java的缓冲流BufferInputStream一直没仔细探讨过其内部实现,查完API文档后才发现其实很简单。就是由BufferInputStream类内部维护一个既定大小的数组,该数组容量默认8192(v1.7),有人说是8M,没验证过。但还有点不明白的地方,就是为何缓冲刘可以提高io效率。百度一番,有所了解,但还是发现有更多的不了解,特别是对IO在接近硬件底层的状况。以下源于(http://zhidao.baidu.com/link?url=1ebEb_JKL8CVCS7p95uO-Q-biIHJxynFRdUQHin_vO-VIrUHPIWviLXftedv6UfNKhxcP_e-pc-GLeNgDUB1OK)

  运用FileInputStream读写一段数据是一个字节一个字节的读取,如果有10个字节大小的文件,就要调用10次系统调用,每次将读取的数据赋值给变量,然后程序使用变量。缓冲区可以看作是一个放在内存中的数组,但是从硬盘中读取数据仍然要使用系统调用,系统调用的读取仍然是每次一个,只是每调用一次之后,将所得到的数据放入缓冲区中的,然后程序一次性使用10个数据。

  但是不管用与不用缓冲区,使用的系统调用是一样多的。调用I\O操作的时候,实际上还是一个一个的读或者写,关键就在,CPU只有一个,不论是几个核心。CPU在系统调用时,会不会还要参与主要操作?参与多次就会花更多的时间。系统调用时,若不用缓冲,CPU会酌情考虑使用中断。此时CPU是主动地,每个周期中都要花去一部分去询问I\O设备是否读完数据,这段时间CPU不能做任何其他的事情(至少负责执行这段模块的核不能)。所以,调用一次读了一个字,通报一次,CPU腾出时间处理一次。而设置缓冲,CPU通常会使用DMA方式去执行I\O操作。CPU将这个工作交给DMA控制器来做,自己腾出时间做其他的事,当DMA完成工作时,DMA会主动告诉CPU“操作完成”。这时,CPU接管后续工作。在此CPU是被动的。DMA是专门做I\O与内存数据交换的,不仅自身效率高,也节约了CPU时间,CPU在DMA开始和结束时做了一些设置罢了。所以,调用一次,不必通报CPU,等缓冲区满了,DMA会对CPU说“嘿,伙计!快过来看看,把他们都搬走吧”。综上,设置缓冲,就建立了数据块,使得DMA执行更方便,CPU也有闲,而不是呆呆地候着I\O数据读来。从微观角度来说,设置缓冲效率要高很多。尽管,不能从这个程序上看出来。几万字的读写\就能看到差距。


你可能感兴趣的:(java,IO)