虚拟内存(virtual memory) = CPU + MMU(Memory Management Unit), MMU是一个CPU上的元器件,它将物理地址映射为虚拟地址,这样CPU可以之别虚拟地址,而不是实际物理地址了。使用MMU的好处有
1、同一个虚拟地址可以指向不同的物理地址;
2、线程之间共享内存变得简单;
当处理器需要访问一块不在内存中的数据数,会产生一个终端,进程处于阻塞状态,数据载入后,阻塞状态变为就绪状态。
硬件及控制结构
Linux内核用struct page结构表示物理页,flags域用来表示状态,包括是不是脏的(修改未落地要物理内存)、是不是被锁定等。_count域存放页的引用计数。该数据结构的意义在于描述物理内存本身,而不是描述其中的数据。
而硬件通过slab层管理分配和释放数据结构(也有很多第三方工具例如tcmalloc取而代之),它扮演的数据结构缓存层的角色。
MMU实现方式
不同于上面提到的page和slab。MMU其实就是一张地址映射表,以32位地址为例,4G的内存大小,也页表项为4KB(大部分操作系统中,内存分配的最小单元就是4KB),留下12bits做偏移量,10bits留给根页表,10bits留给4KB页表。但这种方法有一个致命的缺陷,页表的大小和虚拟地址空间的大小成正比。另一种实现方法是倒排页表,下图摘自《操作系统精髓于设计原理》,总的来说分页和分段是虚拟内存技术的两种方法。
刚刚想到一个狠2的问题,MMU需要做这么多映射,不会爆吗?--当然不会,又不是每个地址都需要映射,只需要映射地址头部就可以了。
分页表
分页表用于记录每页中虚拟内存映射实际内存的信息以及权限等,下图相信会让你一目了然
所以,总的来说,虚拟内存就是一个查询表,这个查询表在CPU中实现。
操作系统软件
- 虚拟内存管理方案要求硬件和软件的支持
- 硬件:
- 虚拟地址动态换成物理地址
- 被访问到的页不存在内存中时,产生一个中断
- 软件:操作系统处理中断中的响应,与之相关的问题有
- 读取策略:请求时读取或者预先读取,使用蔟的方式一次读取多页;
- 放置策略:决定一个进程驻留的实际地方,对纯粹的扥段系统有一些意义,对分页系统无意义;
- 置换策略:当内存满后,必须决定用哪些页换哪些页。大多数策略都基于过去的行为来预测将来的行为。基本算法有OPT(基于预见未来,只存在理论上的可能)、LRU(开销大,难以实现)、FIFO(FIFO策略实施起来简单,但是性能差,因为经常推送错误==!)、时钟(和FIIO唯一不同的是使用为为1的页框会被跳过,同时需要参考是不是访问同时是否被修改来设置置换策略)。另外使用缓冲页技术可以不必真正地将内存置换出去;
- 清除策略:结合缓冲页技术,修改过的进程可以在置换的时候被放置到修改页中,周期写;
- 加载控制:关注任何给定的时刻,驻留在内存中的进程数目;
- 硬件: