点到为止!


源码

说⼀下HashMap的⼯作原理

操作系统

零拷贝

内核空间和用户空间
内核空间(Kernel space)是内核态的运行空间,用户空间(User space)是用户态程序的运行空间。之所以区分的目的是为了安全隔离,即使用户程序崩溃了,内核也不受影响

内核空间可以执行任意命令,调用系统一切资源,用户空间只能执行简单的运算,不能调用系统资源,必须通过系统调用(system call),才能向内核发出指令。例如:

  1. String path = "/usr/local/xxx"; // 用户空间
  2. file.write(path); // 切换到内核空间
  3. String msg = "Hello World"; // 切回到用户空间

该图是从磁盘中读取文件数据通过网络发送给客户端
image.png

从图中可以看出整个读取发送过程中发生了 4 次内核态和用户态的切换,2 次 CPU 拷贝,这些都是相对耗时的操作。

零拷贝
零拷贝指的是数据不需要在内核空间和用户空间之间来回拷贝。从上图中可以看出数据的转换流程,那么我们可以用 DMA 将数据从磁盘文件拷贝到内核缓存区,再从内核缓存区用 DMA 将数据从内核缓存区拷贝到 Socket 缓冲区中,这种整个过程就不需要 CPU 来参与了。

内核缓存区 PageCache 的空间是在内存中的,因此是有限的,如果一个大文件使用零拷贝会占用掉 PageCache 的空间,PageCache 会淘汰掉未使用的数据,这样 PageCache 不仅使用不到,而且浪费 DMA 的性能,因此在大文件时,不使用零拷贝技术。

实现零拷贝的方式

  1. Linux 内核版本必须要 2.1 以上,可以使用 sendfile 函数
  2. 使用 mmap 函数,DMA 会把磁盘的数据拷贝到内核的缓冲区里,然后操作系统直接将内核缓冲区的数据拷贝到 Socket 缓冲区中

参考文章

  1. https://zhuanlan.zhihu.com/p/258513662 非常详细