内存管理
只有地址总线上的地址是真实的物理地址,而在CPU中的地址都是逻辑地址;也就是说只有地址总线操作的内存时物理内存,其他都是虚拟内存。虚拟内存与物理内存的映射就是地址翻译的过程,不同的物理内存管理有着不同的映射方式。
1.内存扩充技术
覆盖技术主要用于早期的操作系统中。交换主要在进程或作业之间完成,而覆盖技术在同一个进程或作业内完成。
1.1 覆盖技术
一个程序不需要将所有的指令与数据放入到内存中,而是将程序划分为若干个相对独立的程序段,按照运行逻辑将那些不会同时运行的程序段共享同一块内存,这样使得用户感觉内存扩大了,从而达到扩充内存的目的,该技术对程序员要求较高;
1.2 交换技术
先将程序中的某一部分程序或数据写入到外存交换区,然后再从外存交换区中调出到指定的程序或数据的内存中来执行相应的操作,从而达到内存扩充的目的。交换技术完全由操作系统完成,整个过程对程序员透明,不需要程序员做特殊的处理工作。
2.物理内存管理
系统运用重定位寄存器防止用户进程非法访问其他进程的地址空间或是篡改操作系统敏感数据,通常将内存分为两个区:内核区和用户区。
内核区位于内存的低地址,中断向量也位于此。而用户区,用于程序的使用,可以将其分给多个进程使用。
内存管理单元(MMU,CPU中的一个模块)将逻辑地址到物理地址的映射如下:
· 基址寄存器:保存了进程物理地址的首地址
· 界限寄存器:保存了逻辑地址的地址范围;任意一个逻辑地址必须小于界限寄存器的值
2.1 段式内存管理
分段式内存管理以段为单位进行内存分配,段与段之间地址可以是不连续的,但是段内地址是连续的。在寻址时,通过段号与段内偏移量即可得到逻辑地址对应的物理地址。
2.2 页式内存管理
进程运行不要求逻辑地址必须是连续的,因此可以将内存空间分为长度一致的数据块,以页为单位进行管理,称为页式内存管理,如下图所示。
· 页帧: 物理空间 等分为长度一致的数据块
· 页: 逻辑空间 等分为长度一致的数据块
上图中,页表可以看做是逻辑地址映射到物理地址的一个目录。通过页号P得到物理地址的页帧号f,然后根据地址偏移量d得到最终的物理地址。
从上图可知,计算机在进行内存映射时,需要进行两次内存操作:
· 第一次是定位到页号P;
· 第二次是从页表获取保存的页帧数据f。
为了解决该问题,操作系统使用**快表(transition look-aside buffer,TLBs)**提高性能,只需要一次内存操作即可得到对应的页帧号f。
快表的特征是支持并行搜索。其实质是一个缓存区,如果页号P在TLBs中(击中),直接从TLB中得到页帧号f;如果没有击中,从内存页表中获取页帧号f。
2.3 段页式内存管理
段页式内存管理集成了段式与页式管理的优点,将内存分为多个段,每个段之间可以不是连续的,而段内进行分页管理,其映射图如下所示。
2.4 碎片处理
内存碎片分为内部碎片与外部碎片。
内部碎片:分出去的分区略大于请求的内存长度。而这个剩下的小块内存属于该分区,无法利用。例如:一个文件为10B,若使用页式管理每一页的大小为4096B,则系统给该文件分配的空间为4096B,剩下的4086B无法被其他文件使用。
外部碎片:内存块集中起来可以满足一个内存请求,但是因为不连续,无法用来连续分配空间。在段式管理中较为常见。
对于内部碎片无法避免,而外部碎片可以通过紧缩操作减少。
紧缩操作:重排内存块,将空闲的内存连续排列,合并成一块较大的内存块。该操作对整个操作系统的性能影响较大,不建议使用。
3.虚拟内存管理
3.1 简介
操作系统在执行进程时,只需要一小部分代码驻留在内存中,这使得物理空间可以被更多的进程共享。实现虚拟内存最为常见的策略是按需调页。
CPU指令包含内存访问,即访问该内存地址所在页面,称为页面引用。
CPU访问内存地址时,存在三种可能:
① 页面已经装入内存,有对应页帧——CPU完成相应操作;
② 非法访问页面——abort;
③ 合法引用,但是页面没有装入内存中——发生缺页中断,将相应页面装入内存中,再次执行相应操作。
缺页中断处理过程,如下图所示:
文字描述为:
1.第一次引用某页面时,对应进程页表项的“有效位”为i(无效),发生缺页中断,操作系统开始响应;
2.操作系统查找内核的数据结构,判断是否是合法引用;
3.操作系统在内核数据结构中找出一个空闲的页帧;
4.把页面从外存(如:磁盘)换入到该空闲页帧;
5.更新内核的数据结构,更新进程的页表;
6.把进程页表向“有效位”置为v(有效),缺页中断返回,重新执行引起缺页中断的指令。
3.2 常见页面置换算法
在处理缺页中断是,如果内存中没有空闲页帧,此时就需要进行页面置换。
常见的页面置换算法:FIFO算法,optimal算法,LRU算法(最近最长时间未使用)。
FIFO算法:替换先加载到内存中的页面;
optimal算法:在所有执行串中,替换使用频率最低的页面。然而,在实际程序中,系统不可能知道哪些程序段是使用频率最低的,这导致optimal算法不可实现。
LRU算法:在之前一定长度的执行串中,哪一个页面距离当前执行串时间最长,那么就将该页面进行替换。该算法的具体实现需要了解。LeetCode No. 146 LRU缓存机制。
系统抖动:当进程数达到一定量时,继续增加进程数,CPU利用率不增反降。此时因为内存不足,导致CPU忙于页面置换,利用率降低,如下图所示。
注:一般操作系统专门存在一个守护进程,kswapd进程(0号进程)进行换出操作。只要磁盘I/O空闲,该进程就会进行扫描,回收空闲内存,换入操作是缺页中断时进行处理。此时,磁盘I/O操作与CPU执行是并行的。