内存超载解决方案
- 交换(swap)
- 虚拟内存(virtual memory)
第一种方案的问题
交换时会导致产生多个空闲区(也称为空洞,hole,类似于磁盘碎片),通过把所有的进程尽可能向下移动,有可能将这些小的空闲区域合成一大块,该技术被称为内存紧缩(memory compaction)
但内存紧缩非常耗时,例如,一台 1GB 内存大小的计算机每 20ns 可以复制 4 个字节,它紧缩全部内存要大约花费 5s。所以内存紧缩操作通常不进行
进程在运行时使用内存常常需要动态增长,如果有相邻的足够使用的空闲区域则没问题,如果相邻内存空间被另一个进程占用,则只能将这个进程移到一段更大的内存中去,如果没有这么大的空间,那么这个进程只能阻塞等待空间,或者死掉
如果大部分运行的进程都需要动态增长内存,那么为了减少进程内存搬运的开销,一种可行的方案是,当换入和移动进程时为它多分配一些预留的内存
速度,典型的 SATA 硬盘读写速度一般不过 100MB/s,意味着大约 10s 才能换出一个 1GB 的程序,再花另一个 10s 才能再将一个 1GB 的程序换入
空闲内存管理
位图
划分内存为许多个小的单位,每个单位用 0 或 1 记录是否空闲
划分单元的大小是一个重要的设计因素。在位图大小和内存单元大小之间要取平衡,且进程的大小一定要是划分单元的整数倍,不然在最后一个分配单元中就会有一定数量的内存被浪费
空闲链表
若 H 代表空闲,P 代表占用
链表可以形如:head: {H, start, length, next} -> next: {P, start, length, next2} -> …
tip: 使用双链表效率会更高
按照以上链表方式管理内存时,为新进程分配内存的算