操作系统有虚拟内存与物理内存的概念。
linux的虚拟内存技术
linux把虚拟空间分成若干个大小相等的存储分区,linux把这样的分区叫做页。为了换入、换出的方便,物理内存也就按页的大小分成若干个块。由于物理内存中的块空间是用来容纳虚存页的容器,所以物理块内存中的块叫做页框,页与页框是linux实现虚拟内存的技术基础。
每页大小为4K,之后进行内存分配是都是以页为单位。
为什么需要虚拟内存?
- 物理内存是有限的,多个进程要执行的时候,都要给4G内存,很显然你内存小一点, 这很快就分配完了,于是没有得到分配资源的进程就只能等待。当一个进程执行完了以后,再将等 待的进程装入内存。这种频繁的装入内存的操作是很没效率的;
- 进程地址空间不隔离,由于指令都是直接访问物理内存的,那么我这个进程就可以修改其他进程的数据,甚至会修改内核地址空间的数据,这是我们不想看到的;
- 程序运行的地址不确定,因为内存时随机分配的,所以程序运行的地址也是不正确的;
虚拟内存和物理内存的联系
虚拟内存和物理内存是通过页表来映射。虚拟地址中前部分是页码,后一部分是偏移值,通过页码在页表中找到对应的物理地址页框,偏移值不变。
一个进程运行时都会得到4G的虚拟内存。每个进程都认为自己拥有4G的空 间,但是实际上,虚拟内存是映射到多个物理内存碎片的,可能只对应的一点点的物理内存,实际用了多少内存,就会对应多少物理内存。
当每个进程创建的时候,内核会为进程分配4G的虚拟内存,当进程还没有开始运行时,这只是一个内存布局。实际上并不立即就把虚拟内存对应位置的程序数据和代码(比如.text .data段)拷贝到物理内存中,只是建立好虚拟内存和磁盘文件之间的映射就好(叫做存储器映射)。这个时候数据和代码还是在 磁盘上的。当运行到对应的程序时,进程去寻找页表,发现页表中地址没有存放在物理内存上,而是在磁盘上,于是发生缺页异常,于是将磁盘上的数据拷贝到物理内存中。
进程访问一个地址的过程
- 我们的cpu想访问虚拟地址所在的虚拟页(VP3),根据页表,找出页表中第三条的值.判断有效位。 如果有效位为1,DRMA缓存命中,根据物理页号,找到物理页当中的内容,返回。
- 若有效位为0,参数缺页异常,操作系统立即阻塞该进程,调用内核缺页异常处理程序。内核通过页面置换算法选择一个页面 作为被覆盖的页面,将该页的内容刷新到磁盘空间当中。然后把VP3映射的磁盘文件缓存到该物理 页上面。然后页表中第三条,有效位变成1,第二部分存储上了可以对应物理内存页的地址的内 容。
- 缺页异常处理完毕后,返回中断前的指令,重新执行,此时缓存命中,执行1。
- 将找到的内容映射到高速缓存当中,CPU从高速缓存中获取该值,结束。