操作系统基础(二) 内存管理

  • 存储分层结构:CPU寄存器->缓存cache->内存memory->磁盘disk
  • 我们希望操作系统能为不同的进程进行内存管理
    • 抽象:逻辑地址空间
    • 虚拟内存:将暂时不用的程序的数据和代码干脆放到硬盘上去
    • 保护:一个进程不能访问其他进程的空间
    • 共享:在需要时,不同的进程可以访问相同的内存空间读写数据  

物理地址、逻辑地址与虚拟内存

  • 物理地址空间:主存、磁盘,由硬件管理
  • 逻辑地址空间:对应用程序来说是连续的,线性的,但实际上在主存甚至磁盘中
  • 逻辑地址生成:不需要操作系统参与,只需要编译链接过程和loader生成
    • 程序的编译过程:预处理->编译->汇编->链接,其中一直到编译得到的汇编语言程序中,函数名和变量名就是表示的逻辑地址空间,然后通过汇编器得到.o可重定位的目标程序,此时就是机器语言,起始地址从0开始的连续地址空间,变量的符号名和函数的符号名被转化为地址(我们知道全局变量和静态局部变量在.dada/.bss中,const变量在只读数据段中)
  • 物理地址生成:CPU中的MMU进行逻辑地址到物理地址的映射,但是映射需要的页表是由操作系统维护的
  • 连续内存分配:将连续的一块物理内存提供给进程使用; 容易出现碎片
  • 非连续内存分配:
    • 更高的内存使用率
    • 不同的进程共享代码与数据
    • 支持动态加载和动态链接
    • 缺点就是管理开销:如何将虚拟地址映射到物理地址
  • 分段
    • 思想是顺应程序本身的分段机制,将程序分段放进物理地址空间中
  • 分页、页表;分页每一页大小固定,而分段则不固定
    • 页表是连续的内存空间,实现虚拟地址到物理地址的映射:虚拟地址4G,按4K的页大小计算,也有1M大小的页表,按物理地址4个字节32位计算,需要4M
    • 实际上页表项不只是存放着物理地址的那4个字节,还存放着标志位:标志位表示这个页表项对应的虚拟地址那一页在物理地址中是否存在,还有是否经过了读、写等  
  • 分页的性能问题及其改善:
    • 逻辑地址空间很大,而每页的空间较小的话,需要的页表本身就很大,根本放不进cache甚至内存(多级页表)
    • 不同的进程都有自己的页表,也很占空间
    • 即使页表放进了内存,每次寻址需要访问内存两次:访问页表项一次,访问页表项的地址的数据一次 
    • 多级页表和缓存解决时间、空间问题
  • CPU内部的TLB(快表)
    • 在MMU内部,key-value非常快地查找虚拟地址对应的逻辑地址
    • TLB Miss则还是会查页表,对应的表项被更新到TLB中(x86是硬件实现更新,MIPS则需要操作系统完成)
  • 二级页表(时间换空间)
    • 为什么能够节省内存空间?
  • 反向页表:为什么页表大呢?因为虚拟地址太大了!那么我们从物理地址映射到虚拟地址,就小了很多
    • 24GB的物理内存空间,按4KB大小帧划分,也才6M,就包含了所有情况!
    • 页寄存器,从物理地址到虚拟地址的映射。
    • 反向查找如何实现?由页号->帧号;用hash表实现

虚拟内存

  为了实现用有限的物理内存,满足多个进程的虚拟内存的使用:覆盖、交换、虚拟内存              

  当运行一个程序时,内核并不会把整个程序完全加载到物理内存中,而是分配好虚拟地址(创建页表),加载可执行文件的部分页面或段到物理内存,只分配了虚拟地址而程序未加载到物理内存的部分,会在页表上做标记。

  当程序运行到只有虚拟地址而没有对应物理内存的地方时,处理器会发生异常,然后内核就分配对应的物理内存页,把磁盘上的数据加载到物理内存,再从异常中返回,程序就能继续运行。异常对用户程序是透明的。

  • 程序的局部性原理:时间局部性和空间局部性;部分交换;不连续性;
  • 虚拟页式内存管理
      • 请求调页:只装入部分页面;缺页异常则请求调页到内存中
      • 页面置换:内存中已然装不下调进来的页了,需要将内存中某些倒霉蛋扔回硬盘
      • 页表表项的标志位:驻留位、保护位(是否能够读、写)、修改位(修改过就和硬盘不一样了)、访问位(是否经常访问)
      • 缺页中断:保护CPU现场、分析中断原因、调用缺页中断服务例程、恢复CPU现场,继续执行进程
      • 硬盘上的换入换出分区,后备存储,Swap分区 
    页面置换算法 
      缺页中断服务例程(所谓中断就是要处理IO的,这里就是磁盘)
      • 先进先出算法FIFO,链表,链表头是驻留时间最长的页   页面进入内存的时间是固定的
      • 最久未使用算法LRU。需要记录每个页的上次使用时间,开销比较大:链表、堆栈  页面上次访问的时间可变
      • 时钟页面置换算法。Clock算法,环形列表,利用页表项中的访问位,操作系统定期将访问位清0。不用更改列表结点 
      • 二次机会法。
      • Belady:物理页越多,反而更多缺页了。  
  • 工作集模型,全局页面置换算法,工作集就是当前时间t之前w时间内某个进程需要访问的页面,驻留集是当前物理内存中实际存在的页面。工作集是程序本身决定的。
    • 平均驻留集越小,同时运行的程序越多,但是如果驻留集小于工作集就会缺页,太小就会频繁缺页
    • 驻留集尽量覆盖工作集,如果有尸位素餐的就换出
    • 缺页率用来动态调整工作集大小 
    • 抖动问题 驻留集小于工作集,使得频繁发生页面交换,CPU利用率低。
      • 一般平均驻留集越小,多道程序度越高,CPU利用率越高才对
      • 但是多道程序度MPL高到一定程度就就会抖动,CPU利用率急剧降低
      • 将其他进程挂起

  假设矛盾不可调和,就是物理内存不够用了,那么怎么办呢?这就涉及到新的知识:进程与进程调度。     

  

 

posted @ 2019-09-01 12:03  LiaoQian1996  阅读(164)  评论(0编辑  收藏  举报