起因
上次不是说因为没有用缓冲流写文件io过高会导致cpu变高吗。但是虽然有这个现象,但是不知道是怎么回事。
之前在加班,没有怎么细想。这段时间,闲下来后,本着程序员的探索精神去查阅各种资料。偶有所得。记录于此
对比
很明显,使用缓存流和不使用缓存流的最大区别就是一个会高频次读写外部文件,一个是先写内存,然后再低频大批量写入外部文件。
上篇文章只是粗暴的给出了一个结论。那就是cpu会等待写入完成。但是原因依然不得而知。为什么缓存写入这么快也是不得而知
操作系统底层调用
经过一番查阅。我知道了。java的文件写入都会触发操作系统底层的write()函数
而write()函数是属于系统调用。也就是触发一次就会从用户态切换到内核态。而这会导致 CPU 花费更多的时间在内核空间和用户空间之间切换。每次切换都会导致数据反复复制。文件描述符反复传递读取。这些都是需要cpu干涉的。
ps:关于内核态和用户态的性能优化在netty框架体现得非常明显。甚至netty直接使用了零拷贝技术通过DMA无需cpu进行干预。
物理底层调用
我们知道如果电脑的硬盘是磁盘。那么文件每次写入都会移动移动磁盘头和磁臂。那么每个字节或者每个字符的写入都会导致反复移动。而批量写入就简单多了。是一种连续性的写入。所以写入效率高很多。
总结
以后写文件,要最好使用缓冲流式的写入。这样子会减少文件描述符的读取。磁盘的随机访问,内核的切换。
有得就有失去,唯一的缺点就是占用了一点点的内存做缓存,以及断电时可能来不及写入。