内存管理

来源:互联网 发布:大富翁数据 编辑:程序博客网 时间:2024/06/05 03:37

分层存储器:寄存器,高速缓存,内存,磁盘,可移动存储
操作系统中管理分层存储器体系的部分称为存储管理器 memory manager。

地址空间:一种存储器的抽象。

存储资源的分配和回收:记录空闲、占用内存,分配与释放内存用。
地址变换:可执行文件生成中的连接技术。

程序加载(装入)时的重定位技术:对于内存连续分配的情况,多道程序不同进程的指令调用的是自己进程地址空间(从0开始)的相对位置的内容,这在实际的物理内存中不是这样的,需要利用基址寄存器与界限寄存器来确定其真实的内存地址。即完成从逻辑地址到物理地址的转换。
保护:不允许进程访问其内存区域之外的数据。
但多了加法和比较运算。

进程运行时硬件和软件的地址变换技术和机构

存储共享与保护:代码和数据共享;地址空间访问权限(读写执行)
存储器的扩充:将内存扩大,使尽可能多的可运行进程装入内存。
由应用程序控制:覆盖,
  覆盖技术:将程序分为若干段,使不同时运行的程序段映射到同一地址空间。
由OS控制:交换整个进程地址空间;虚拟内存的请求调入和预调入部分进程空间

交换技术与可变分区管理

  内存扩充的一种:将暂时不能运行的进程的图像调出内存。
  在硬盘上维护一个盘交换区。盘交换区与内存之间的调入调出是属于高级调度范畴。 通过不断地交换进程的图像(高级调度),使处于不同存储部位上的进程都有公平的cpu占用机会。
  
  复习:两级调度法。一般情况下正在运行的进程都在内存中。如果没有足够的内存,则某些进程的进程图像将全部或部分地被放在磁盘上。
  低级调度 —— 低级调度程序选择当前在内存中的就绪进程占用cpu
  高级调度 —— 高级调度程序实现进程在内存和磁盘间来回交换(时机与实施)标准包括:进程自上次被换入或换出以来的时间,进程最近使用的CPU时间,进程图像的大小,进程的优先级
  在UNIX SVR4中,内存与盘交换区的互动就是高级调度。

  内存分配变化:即内存的块状分配与回收。
  会出现碎片、进程的数据段与堆栈的增长、内存空间按什么原则来分配给进程:
  解决方案:1.内存紧缩
  2.再分配内存
  3.确定内存分配算法

  首先,要对内存的空闲与占用部分进行管理。
  位图表示法: 查找时,查找连续1串,实施管理的辅助空间是一定的成本。
  分配单位的大小因素的影响:
  大: 位图占用空间小,分配的内存浪费大
  小: 位图占用空间大,分配的内存浪费小

  使用链表的内存管理。
  将已分配的内存段和空闲的内存段用链表管理起来。P占用空间不需要在链表中 ,相连空洞合并相连,辅助空间大小会变。
  改进:将已分配的内存段和空闲的内存段分别用链表管理起来。
   链表中的结点按段的长度从小到大排序或按段的起始地址从小到大排序。

  空闲内存的分配算法:
  首次适配法 从头部开始查找,
  下次适配法 起始点逐次向后移动
  最佳适配法 找一样的碎片 碎片小
  最差适配法 找对比度最大的,碎片比较大,碎片化低
  快速适配法 为那些常用大小的空闲区维护单独的链表。
  linux的存储空间分配: 伙伴算法

http://www.cnblogs.com/huhuuu/p/3598760.html
  
  内存交换时的sched进程的工作
  

虚拟内存与分页技术

  物理内存分配的不连续。
  调入调出是部分交换的。是对部分虚拟地址空间进行的。
  关键: 构造地址映射表: VA–>PA
  分页技术:页面、页表、页框
  页面到页框之间的映射通过页表来完成,由OS维护进程的调入调出所引起的映射表变化。
  页表在CPU的MMU内存管理单元中,维护在内存中。
  MMU的工作原理,截取高位作为索引字,找到页框号,低位作为偏移量。
  分页技术的优点:没有外碎片,每个内碎片不超过也大小
  一个进程的图像在内存中不必连续存放,便于改变进程图像占用内存空间的大小。
  页表项的结构:在不在位,保护位,页框好,禁止缓存位,引用位
  页表需要较大的内存空间,而且是连续的内存空间。
  通过页表完成的地址映射需要访问一次内存。
  引入多级页表:使页表不必占用连续的内存空间。
  引入快表TLB:加快映射的过程,如何加快?
  将页表的部分内容存放在MMU中的硬件寄存器中,通过硬件直接查找页框号。
  TLBs表相当与CPU中的一个小页表。TLBs表项一般不多于64;每个表项包含页表项,以及其他信息;匹配是并行的,由硬件完成;TLB的内容从页表生成,随进程的推进而调整。
  内存读取的三种情况
  缺页中断——要到外存拿,页面调入
  快表命中——直接从内存拿
  页表命中——从内存中索引页表去拿
  
  逆向页表:
  64位所需的表项很多,页表就很大很大了。
  可以反过来对有页框数个页表项的真实页表。依据该进程在内存中实际占用的物理页面来组织页表。
  问题是:从虚地址到物理地址的变换变得十分困难,需要遍历
  解决方法:使用快表或使用哈希表组织逆向页表
  通过哈希表作为逆向页表的索引

页面替换算法

  页框是有限,当发生缺页中断时,新载入内存的页面该去替换那个已有页表项呢?
  基本思想:尽可能选择不太会再使用的页面淘汰
  页面替换算法
  1.最优页面替换算法
  计算出多少条指令后该页面被再次使用,淘汰最晚将会遇到的。
  实际不可能实现,但可作为标准来评估
  2.最近未使用页面替换算法(NRU)
  页表项中的引用位R于修改位M
  淘汰顺序:最近时钟周期内被使用过,也被修改过<最近时钟周期内被使用过,没被修改过<最近时钟周期没内被使用过,被修改过<最近时钟周期没内被使用过,没被修改过
  3.先入先出页面替换算法(FIFO)
  不考虑使用情况,不好
  运用改良的
  4.第二次机会算法
  链头的页表项如果R为1,将其插入链尾给次机会。
  5.时钟页面替换算法(是对第二次机会算法的改进)
  环状链表,只需表头指针移动即可。
  Solaris的双表头算法:
  6.最久未使用页面替换算法(LRU)
  淘汰掉没有使用的时间最长的页。
  方法1:用一个链表管理在内存中的所有正在使用的页面,最近使用的页在表的尾部,最久未使用的页在表的头部。
  每次访问内存时,在链表中找到当前被访问的页,将它移动到链表的尾部。这是一个非常费时的操作(软件实现)
  在页面故障发生时,淘汰掉链表头部的页面。
  方法2:设置1个64位的计数器C,每执行一条指令,C加1.
  每次访问内存页面时,将C值存入该页面的页表项。
   淘汰计数值最小的页面。但是之前频繁使用的页C值很大,就算最近都不用了,也没办法把它淘汰,应该使用老化方法优化。
   方法3:LRU硬件维持一个n*n的矩阵,使用到时k行都设置1,k列都设为0
   7.软件模拟的LRU算法(NFU)
   每个页面都有一个软件计数器,初值为0
   每个时钟中断周期,使用过的加1.
   这就是上面所说的LRU方法1的软件实现。
  老化改进,计数器右移一位,R为加到最左端。
  每个进程都会维护一个自己的页表。

分页系统设计的问题

  为什么只有当某一页被要求时才调入内存?
  自然页流的连续性、局部性
  当正在运行的进程数量增加到一定程度时,CPU的使用率反而下降。出现系统颠簸。
  为什么会出现系统颠簸?
  如何减少进程的页面故障?
  引入工作集模型-跟踪进程的工作集
  控制内存中的进程数
  
  局部与全局页面分配策略:
  当进程pa发生页面故障时,淘汰的页面是在进程pa的页面中找?(局部分配)还是在内存中的所有页面中找?(全局分配)
  最优方法:进程按比例分配初始页面数 + 全局分配页面
  页面的大小:
  页面小则  
—— 页表占用的内存空间 ==> 大
—— 最后一页的浪费(内零头) ==> 小
—— 磁盘传输的开销(磁盘一次传输一页) ==> 大
—— 内存的利用率 ==> 高
—— 内存的附加开销 = e × ( s / p ) + p/2
最佳大小√(2se) s为进程图像大小,e为页表项的大小。

  分离指令空间(正文段)与数据空间I空间与D空间
  好处:进程的地址空间变大
  由于事先进程之间共享正文段
  执行同一个程序的多个进程可以共享正文段
  数据段也可以共享(fork)
  单个页面也可以被共享(shared memory)
  内存映射的文件:mmap系统调用:内存映射,简而言之就是将用户空间的一段内存区域映射到内核空间,映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间。那么对于内核空间<—->用户空间两者之间需要大量数据传输等操作的话效率是非常高的。
  如果两个或两个以上的进程同时映射了同一个文件,他们就可以通过共享内存来通信。
  共享库也可以通过内存映射的文件来实现。当一个共享库被装载和使用时,整个库并不是一次性读入内存,而是根据需要,以页为单位装载的。如果其他程序已经装载了该共享库,就没必要再次装载它了。
  Copy on write:allows both parent and child processes to initialy shared

  页面错误处理过程
  1.Hardware traps to kernel
  2. General registers saved
  3.OS determines which virtual page needed
  4. OS checks validity of address, seeks page frame
  5.If selected frame is dirty, write it to disk
  6.OS brings schedules new page in from disk
  7.Page tables updated
  8. Faulting instruction backed up to when it began
  9.Faulting process scheduled
  10. Registers restored
  11. Program continues
  
  有时存在同一个页面被两个进程污染的情况,所以当一个页在读磁盘时,需要锁住这个页,不被其它进程页面错误处理给抢占。
  后备存储:
文件地址空间
????

分页式虚存:

进程生成
确定程序大小
创建页表
Memory Mapped files
进程切换
页面错误
进程终结

同一个文件映射到不同的进程地址空间里。动态连接文件,数据共享。strace的作用,mmap,地址空间大小。

高级调度 就绪的进程尽量在内存中
只要一部分在内存中即可

进程换入换出 : 哪些要常住内存
正文段、共享内存端 不能换出
proc结构:文件管理相关 user结构 进程调度相关信息 受阻进程,收到信号能被唤醒 proc随时可能被查看

高级调度工作不展开
一进程方式工作,可以睡眠,低级调度随时可被外部事件触发,不以进程运行,是构成进程模型的机制部分

分页式的内存管理:page
虚拟存储管理: 运行模式
扩大内存:交换 、覆盖、虚拟存储管理
地址空间可以没有全部在内存中,栈段GAP正文段数据段,有些可以在磁盘中
不连续性 物理内存分配的不连续,虚拟地址空间使用不连续
放入可执行的最小页数即可运行
部分交换:不是整体交换,而是按最小颗粒段位PAGE进行交换

部分装入,即可运行 (就绪状态)
现时需要,马上调入 -缺页,最常见的受阻状态 。通知将相应的页或段调入内存,然后执行程序

暂时不用,移出主存 -移到磁盘的盘交换区、或文件间隙

实现的基本思想:VA 程序地址空间 虚拟空间 逻辑空间
PA物理地址空间 内存地址空间 分页技术 分段技术
构造地址映射表:VA->PA

分页技术:
程序地址空间和内存地址空间分成多个页和页框或页帧
页和页框相互映射——页表
OS维护进程的调入调出所引起的映射表变化

页表 映射表的位置:MMU : Cache 使用过的保存在cache中,快表
映射表的大小:挺大 会放在内存中

页表太大,打散页表。 多级页表,多次访问 64位之后

多级页表的空间也很大,利用时间换空间,有3次访问内存,P位设置为1。

快表MMU TLBs 有3个情景。Case1

逆向页表 类似 快表(硬件并行匹配)
页号 页框 快速搜索,索引 Hash表 查找与表长没有关系
表是逆向形成的 页框装入引起表的产生
多级页表还是主流的

怎么将虚地址转化为实地址?

页面替换算法:
有效的管理页框:
自然页流的连续性:
最近的过去用过了,最近的将来可能还会用

最近未使用页面替换算法NRU
R位引用位:被访问 置1
M位修改位:被写 置1
时钟滴答:在两个滴答之间发生过的引用
将页面分成4类,淘汰类数小的那些

FIFO

第二次机会页面替换算法:

时钟页面替换算法:
双手臂时钟

最久未使用页面替换算法LRU
单链表维护
设置一个计数器,问题在于C会溢出,64位计数器,在页面中这个数据量太大了。
LRU 硬件维持一个n*n位的矩阵,需要硬件支撑

用软件模拟LRU算法 NFU
累加R位的值
先往低位移,再把新的R位加到最高位:改进后的老化算法

1 0
原创粉丝点击