操作系统内存管理!

DMA(Direct Memory Access 直接内存访问)

DMA意味着在不涉及CPU的情况下依然可以读取/写入内存,即DMA不需要CPU的支持。

控制直接内存访问的过程。

DMA的优点:

缓解总线上的拥塞。

DMA设备可以直接在内存之间传输数据,而不是使用CPU作为中介。

提升系统并发,CPU可以去处理别的任务了。

页面缓存(Page Cache)

由于读写硬盘的速度比读写内存要慢很多。

为了避免每次读写文件时,都需要对硬盘进行读写操作,Linux 内核会以页大小(4KB) 为单位,将文件划分为多数据块。

当用户对文件中的某个数据块进行读写操作时,内核首先会申请一个内存页(称为页缓存)与文件中的数据块进行缓存。

操作系统是如何管理虚拟地址与物理内存地址之间关系?

主要有三种方式,分别是分段、分页、段页

内存分段

程序包含若干个逻辑分段,如可由代码段、数据段、栈段、堆段组成,每个分段都有不同的属性。

所以内存以分段的形式把这些段分离出来进行管理。

分段管理下的虚拟地址由两部分组成,段号和段内偏移量。

  • 通过段号映射段表的项
  • 从项中获取到段基地址
  • 段基地址+段内偏移量=使用的物理内存

不足之处:

  • 内存碎片的问题
  • 内存交换的效率低的问题

image-20231011095850049

内存分页

分段的好处是能产生连续的内存空间,但是会出现大量内存碎片与内存交换效率低的问题。

分页是把整个虚拟与物理空间切成一段段固定尺寸的大小。

这样一个连续并且尺寸固定的空间叫页,在 Linux 下,每一页的大小为 4KB。

虚拟地址与物理地址是通过页表来映射,虚拟空间内的虚拟地址一定是连续的,物理地址不一定。

但可以通过连续的虚拟地址把多个不连续的物理内存组合使用。

  • 页号找到页表中的页项

  • 获取页项的物理页号基地址

  • 偏移量+物理页号基地址计算出物理内存地址

而当进程访问的虚拟地址在页表中查不到时,系统会产生一个缺页异常,进入系统内核空间分配物理内存、更新进程页表。

最后再返回用户空间,恢复进程的运行。

image-20231011095850049

image-20231011095850049

内存段页

段式与页式并不是相对的,他们也可以组合在一起使用,在段的基础上进行分页分级。

先将程序划分为多个有逻辑意义的段。

接着再把每个段划分为多个页,也就是对分段划分出来的连续空间,再划分固定大小的页。

虚拟地址结构由段号、段内页号和页内位移三部分组成。

  • 通过段号获取段表的段项

  • 通过段项获取到页表地址

  • 通过页表地址找到段页表

  • 通过段内页号找到段页表的段页项

  • 通过段页项获取物理页基地址

  • 通过物理页基地址+偏移量计算出物理内存地址

image-20231011095850049

虚拟内存

实际上运行的进程并不是直接使用物理内存地址,而是把进程使用的内存地址与实际的物理内存地址做隔离。

即操作系统会为每个进程分配独立的一套虚拟地址

每个进程玩自己的地址,互不干涉,至于虚拟地址怎么映射到物理地址,对进程来说是透明的。

操作系统已经把这些安排的明明白白了。

操作系统会提供一种机制,将不同进程的虚拟地址和不同内存的物理地址映射起来。

image-20231011095850049

MMU内存管理单元:

在 CPU 中一个小型的设备,内存管理单元(Memory Management Unit, MMU)。

当 CPU 需要执行一条指令时,如果指令中涉及内存读写操作,CPU 会把虚拟地址给 MMU。

MMU 自动完成虚拟地址到真实地址的计算。

然后,MMU 连接了地址总线,帮助 CPU 操作真实地址。

页面置换算法

在地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断。

当发生缺页中断时,如果操作系统内存中没有空闲页面。

则操作系统必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。

而用来选择淘汰哪一页的规则叫做页面置换算法。

最佳置换算法(OPT )

这是一种理想情况下的页面置换算法,但实际上是不可能实现的。

该算法的基本思想是:

发生缺页时,有些页面在内存中,其中有一页将很快被访问(也包含紧接着的下一条指令的那页)。

  • 而其他页面则可能要到 10、100 或者 1000 条指令后才会被访问。

每个页面都可以用在该页面首次被访问前所要执行的指令数进行标记。

最佳页面置换算法只是简单地规定:标记最大的页应该被置换,这个算法唯一的一个问题就是它无法实现。

当缺页发生时,操作系统无法知道各个页面下一次是在什么时候被访问。

虽然这个算法不可能实现,但是最佳页面置换算法可以用于对可实现算法的性能进行衡量比较。

先进先出置换算法(FIFO )

总是选择在主存中停留时间最长(即最老)的一页置换,即先进入内存的页,先退出内存。

  • 理由是:最早调入内存的页,其不再被使用的可能性比刚调入内存的可能性大。

最近最久未使用(LRU )算法

LRU 算法是与每个页面最后使用的时间有关的。

当必须置换一个页面时,LRU 算法选择过去一段时间里最久未被使用的页面。