内存的组织
我们计算机并不是按字节来在管理内存的,而是通过”页”这个概念,一页有若干字节.
就像我们描述一本书的厚度时.通常说一本书有多少页,而不是说这本书有多少字.
假设我们计算机是12位的,那么一共有
212
2
12
个字节,我们假设一个页的大小是64个字节那么我们的计算机就有64页,
其中,
26
2
6
个字节用6个比特位可以表示
将其画出来就是如图所示的结构
形象来说页号就是”一本书的页数”,页偏移就是每页的”字数”,而这本书的特点就是每页上的字数都是一样的.
虚拟内存
虚拟内存说是内存,其实是一个存放在磁盘上N个连续的空间,里面存有数据. 当它被置入内存中,就变成了实实在在的内存.
它的存储结构也是和物理内存一样的,如图所示
我们用虚拟页(virual page)来描述某一块虚拟内存空间,任何时候
虚拟页只有三种状态
在磁盘没有被创建(没有被分配)
在磁盘上创建出来了,等待被加入内存中
已经被加在入内存了
虚拟内存和物理内存的映射
要把虚拟内存装入物理内存,就要有虚拟地址VA和物理地址PA的一个映射关系.这个关系是由操作系统,MMU实现,存放在物理内存中一个叫页表(page table)的数据结构来维护的
页表是一个页表条目(Page Table Entry)的数组,虚拟地址空间中的每个页在页表中一个固定的偏移量都有一个PTE, 假设PTE还有一个有效位表示该虚拟地址的状态,1表示已经创建了虚拟地址,0表示没有创建.而pte指向的内容就是物理地址.
简单来讲,页表这种映射关系就是数组,其中pte内容是(虚拟地址+有效位
), 把pte当作下标,那么pte指向的内容就是物理地址
当然如果虚拟内存大于物理内存,一个虚拟地址就必须能被映射在多个物理内存的地址,通常有直接映射和全映射,组间映射. 这里采用的是全映射,即:任意一块虚拟内存可一倍映射在任意一块物理内存.
使用虚拟内存的好处
我们知道,程序是存储在硬盘上的,程序运行起来变成进程,才加载入内存,物理内存是占用一个少一个,怎么保证不同进程之间的数据不会发生冲突呢?
假设实际上我们的程序在运行起来时使用的是一片全新的虚拟内存,
一大片空间随意挥霍,最后通过页表的映射成物理地址,就可以解决数据冲突的问题,
而且我们可以规定哪一片虚拟空间是只读的,是不可访问的,在页表里将其标记,如果违反标记就强制中断翻译成物理地址的过程,保护了我们的程序和物理内存.
如何翻译虚拟内存
cpu在执行程序读取数据时,使用的是虚拟地址.
在CPU内部有一个MMU单元,他通过从CPU接受到的虚拟地址生成一个PTEA(上文中pte的地址)
在cache或者内存中通过PTEA找到了PTE,就把他送至MMU,PTE中有对应的物理地址,MMU解析后就将这个物理地址(pa)送至内存或者缓存中进行读取数据(注意 cpu大多情况下是和缓存打交道)
缺页
在虚拟地址和物理地址映射时,当然还有一种情况是通过PTE发现虚拟地址没有对应的物理地址,( PTE有效位为0 ) 就会引发一个”缺页的异常”
我们知道PTE有效位为0 有两种状态,若这个虚拟页没不存在,这时候程序崩溃(一种可能程序是把任意整型赋值给指针 去解引用指针).
另一种状态是虚拟页已经存在,但是没有被加载入内存中, 叫做硬性页缺失
那么操作系统会寻找物理内存空闲的地方 从磁盘加载虚拟页到内存
或者指定内存中一个”已经修改过的页面”(狭义上就是已经读取,修改过该内存的数据)写入磁盘,再把虚拟页从磁盘写入内存
和CPU内存之间有一个缓存SRAM一样, 磁盘和内存也是通过一个DRAM缓存来交换数据的,当发生硬性页缺失时,内存会进入磁盘读写数据
内存和硬盘打起交道 硬盘就像那个 树懒Flash
内存向硬盘提问题用了1秒
硬盘反应过来 要花一天的时间
硬性页缺失导致的性能损失是很大的。以一块7200rpm的主流机械硬盘为例,其平均寻道时间为8.5毫秒,读入内存需要0.05毫秒。相对的,DDR3内存的访问延迟通常在数十到100纳秒之间,性能差距可能会达到8万到22万倍。
形象的说,如果发生硬性页缺失,电脑性能会瞬间下降8万到22万倍.
为什么使用一键加速是个不好的习惯
所有管理内存的一件加速软件都是将内存中大量已经在运行的软件结束掉,表面上内存空闲出来了,但是cpu所需要的数据在内存中找不到,当你再使用这个软件时,会发生缺页,内存会大量的访问硬盘,硬盘接收到大量的IO信号,便会加速地运转,你会明显听到硬盘转动发出的噪音,并且电脑会瞬间变卡.
所以在内存中保持一定常驻的程序,很大程度上可以维持电脑的流畅性.
参考: <<深入理解计算机系统>>