拷贝(Zero-copy)技术指在计算机执行操作时,CPU 不需要先将数据从一个内存区域复制到另一个内存区域,从而可以减少上下文切换以及 CPU 的拷贝时间 。
它的作用是在数据报从网络设备到用户程序空间传递的过程中,减少数据拷贝次数,减少系统调用,实现 CPU 的零参与,彻底消除 CPU 在这方面的负载 。
实现零拷贝用到的最主要技术是 DMA 数据传输技术和内存区域映射技术:
- 零拷贝机制可以减少数据在内核缓冲区和用户进程缓冲区之间反复的 I/O 拷贝操作 。
- 零拷贝机制可以减少用户进程地址空间和内核地址空间之间因为上下文切换而带来的 CPU 开销 。
由于操作系统的进程与进程之间是共享 CPU 和内存资源的,因此需要一套完善的内存管理机制防止进程之间内存泄漏的问题 。
为了更加有效地管理内存并减少出错,现代操作系统提供了一种对主存的抽象概念,即虚拟内存(Virtual Memory) 。
虚拟内存为每个进程提供了一个一致的、私有的地址空间,它让每个进程产生了一种自己在独享主存的错觉(每个进程拥有一片连续完整的内存空间) 。
物理内存
物理内存(Physical Memory)是相对于虚拟内存(Virtual Memory)而言的 。
物理内存指通过物理内存条而获得的内存空间,而虚拟内存则是指将硬盘的一块区域划分来作为内存 。内存主要作用是在计算机运行时为操作系统和各种程序提供临时储存 。
在应用中,自然是顾名思义,物理上,真实存在的插在主板内存槽上的内存条的容量的大小 。
虚拟内存
虚拟内存是计算机系统内存管理的一种技术 。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间) 。
而实际上,虚拟内存通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换,加载到物理内存中来 。
目前,大多数操作系统都使用了虚拟内存,如 windows 系统的虚拟内存、linux 系统的交换空间等等 。
虚拟内存地址和用户进程紧密相关,一般来说不同进程里的同一个虚拟地址指向的物理地址是不一样的,所以离开进程谈虚拟内存没有任何意义 。每个进程所能使用的虚拟地址大小和 CPU 位数有关 。
在 32 位的系统上,虚拟地址空间大小是 2^32=4G,在 64 位系统上,虚拟地址空间大小是 2^64=16G,而实际的物理内存可能远远小于虚拟内存的大小 。
每个用户进程维护了一个单独的页表(Page Table),虚拟内存和物理内存就是通过这个页表实现地址空间的映射的 。
下面给出两个进程 A、B 各自的虚拟内存空间以及对应的物理内存之间的地址映射示意图:
文章插图
当进程执行一个程序时,需要先从内存中读取该进程的指令,然后执行,获取指令时用到的就是虚拟地址 。
这个虚拟地址是程序链接时确定的(内核加载并初始化进程时会调整动态库的地址范围) 。
为了获取到实际的数据,CPU 需要将虚拟地址转换成物理地址,CPU 转换地址时需要用到进程的页表(Page Table),而页表(Page Table)里面的数据由操作系统维护 。
其中页表(Page Table)可以简单的理解为单个内存映射(Memory MApping)的链表(当然实际结构很复杂) 。
里面的每个内存映射(Memory Mapping)都将一块虚拟地址映射到一个特定的地址空间(物理内存或者磁盘存储空间) 。
每个进程拥有自己的页表(Page Table),和其他进程的页表(Page Table)没有关系 。
通过上面的介绍,我们可以简单的将用户进程申请并访问物理内存(或磁盘存储空间)的过程总结如下:
- 用户进程向操作系统发出内存申请请求 。
- 系统会检查进程的虚拟地址空间是否被用完,如果有剩余,给进程分配虚拟地址 。
- 系统为这块虚拟地址创建内存映射(Memory Mapping),并将它放进该进程的页表(Page Table) 。
- 系统返回虚拟地址给用户进程,用户进程开始访问该虚拟地址 。
- CPU 根据虚拟地址在此进程的页表(Page Table)中找到了相应的内存映射(Memory Mapping),但是这个内存映射(Memory Mapping)没有和物理内存关联,于是产生缺页中断 。
- 操作系统收到缺页中断后,分配真正的物理内存并将它关联到页表相应的内存映射(Memory Mapping) 。中断处理完成后,CPU 就可以访问内存了
- 当然缺页中断不是每次都会发生,只有系统觉得有必要延迟分配内存的时候才用的着,也即很多时候在上面的第 3 步系统会分配真正的物理内存并和内存映射(Memory Mapping)进行关联 。
推荐阅读
- 淘宝从百万到千万级并发的14次服务端架构演进之路
- 几百万扔进水?买二手房千万避开这几类房源
- 分布式、高并发、多线程,这些概念还傻傻分不清吗?
- Java 并发编程:如何保证共享变量的原子性?
- 硬核!如何模拟 5w+ 的并发用户?
- 格鲁吉亚中国茶王刘峻周诞辰150周年之际获百万赔偿
- 安徽省科技厅强化科技支撑推进精准扶贫
- PHP导出百万条数据方法
- 重金寻人 , 你是我们要找的百万英雄吗 内含福利
- 带你深入了解高并发架构