操作系统为每一个进程分配一套虚拟地址。进程与进程之间隔离开来,互不干涉。
操作系统会提供一种机制,将不同进程的虚拟地址和不同内存的物理地址映射起来。
操作系统是如何管理虚拟地址和物理地址之间的关系?
程序是由若干逻辑分段组成的,如可由代码分段,数据分段,栈段,堆段组成,不同的段是具有不同的属性,所以就用分段的形式把这些段分离出来。
虚拟地址是通过段表与物理内存进行映射,分段机制会把程序的虚拟地址分为4个段,每个段在段表中有意向,再这一项找到段的基地址,再加上偏移量,于是就能找到物理内存中的地址。
分段的不足之处
外部内存碎片,也就是产生了多个不连续的小物理内存,导致新的程序无法被装载。
因为硬盘的访问速度比内存慢太多了,每一次内存交换,我们都需要把一大段连续的内存数据写到硬盘上。
为了解决内存碎片和内存交换效率低的问题就出现了内存分页
分段的好处是能产生连续的内存空间,但是会出现内存碎片和内存交换的空间太多的问题。
要解决这个问题就要想出能少出现一些内存碎片的办法,另外当需要进行内存交换的时候,让需要交换写入或者从磁盘装载的数据更少一些,这样就可以解决问题,这个办法就是内存分页。
分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小,这样一个连续且尺寸固定的内存空间,称为“页”, 在LINUX 下每一个页的大小为4KB
页表是存储在内存里面,内存管理单元(MMU)就做将虚拟内存地址转换为物理地址的工作
当进程访问的虚拟地址在页表中查找不到时候,系统就会产生一个缺页异常,进入系统内核空间分配物理内存、更新进程页表、最后再返回用户空间,恢复进程的运行。
由于内存空间是预先划分好的,也就不会像分段会产生间隙非常小的内存,这正是分段会产生内存碎片的原因,而采用了分页,那么释放内存都是以页为单位释放的,也就不会产生无法给进程使用的小内存。
由于内存空间的不足,操作系统会把其他正在运行的进程中的“最近没被使用”的内存页面给释放掉,也就是暂时写在硬盘上,称为换出(swap out)。 一旦需要的时候,再加载进来,称为换入。所以,一次性写入磁盘的页只有少数的一个页或者几个页,不会花太多时间,内存交换的效率就相对比较高。
更进一步地,分页的方式使得我们在加载程序的时候,不在需要一次性的都把程序加载到物理内存中,我们完全可以再进行虚拟内存和物理内存的页之间的映射之后,并不真的把页加载到物理内存去,而是只有在程序运行中,需要用到对应虚拟内存里面的指令和数据时,再加载到物理内存里面去。
原文:https://www.cnblogs.com/wsl-hitsz/p/15001699.html