内存管理的需求
重定位
当进程在内存和磁盘中交换的时候,需要通过重定位将进程放到内存的不同区域。
处理器和操作系统通过某种方式把代码中的内存访问转换成物理内存的地址,并反映在内存中的当前位置。
保护
每个进程应该受到保护,以免被其他进程干涉。必须在运行时检查进程产生的所有内存访问,以确保它们之访问了分配给该进程的存储空间。
内存保护必须由处理器硬件来满足,而不是由操作系统软件来满足。
共享
允许多个进程访问内存的同一部分。
逻辑组织
操作系统和计算机硬件有效地处理以某种模块的形式组织的用户程序和数据。
物理组织
存储器分为内存和外存。两级存储器移动信息是系统责任。
内存分区
固定分区
使用大小相等的分区和大小不等的分区。
大小相等的问题:程序可能太大放不进,内存利用率低,导致大量内部碎片。
大小不等的分区可以缓解这个两个问题,但是不能完全解决。
放置算法:
- 对于大小相等分区:只要存在可用的分区,进程就可以装入。如果所有分区都被不可运行状态的进程占据,则需要换出一些,从而为新进程让出空间。
- 对于大小不等分区:最简单的方法就是将每个进程分配到能够容纳它的最小分区。这样,每个分区都要维护一个调度队列,用于保存这个分区换出的进程,优点是,每个分区浪费的空间最少。但是从这个系统来看,这样的策略不是最佳的。更好的方法是,为所有进程只提供一个队列,需要装入分区的时候,选择可以容纳的最小分分区,如果都占满,则有限考虑换出最小分区内的进程。
动态分区
分区的长度和数目是可变的,进程被装入内存后,系统会给它分配一个容量完全相等的内存。
动态分区开始的时候很好,但是随着时间推移,内存中会产出越来越多的碎片,利用率下降,这种称为外部碎片指的是分区外的存储空间碎片。
克服外部碎片的一种技术是压缩,将进程内存排列在一起,但是会非常费时。压缩需要重定位的能力。
放置算法:将进程放到合适的外部碎片内,有最佳适配、首次适配和下次适配。最佳适配选择与要求的大小最接近的块;首次适配从头开始扫描,选择大小足够的第一个块;下次适配从上次放置的位置开始扫面,选择下一个大小足够的可用快。
首次适配算法最简单,而且通常也时最好和最快的。最佳适配性能最差。
伙伴系统
固定分区限制了活动进程的数目,内存利用率低。动态分区维护复杂,需要压缩的额外开销。更好的折中方案时伙伴系统。
先将内存分为可分配的最小尺寸的块,每两个相邻的块为一组伙伴。如果进程满足一个最小伙伴的大小,则直接分配空间,如果进程大于伙伴的大小,则两个伙伴结合为一个,直到满足要求,若进程小于一个伙伴的二分之一大小,则这个伙伴分裂为两个伙伴。
重定位
将相对地址转化为物理内存地址。
分页
将进程划分成同样大小的块,将内存划分为大小固定相等的块,进程中称为页的块可以指定到内存中称为页框的可用块。就是分页技术。
浪费的空间仅仅是最后一页的小部分内部碎片,没有外部碎片。
操作系统需要为每个进程需要维护一个页表。页表给出了该进程每一页对应的页框的位置。每个逻辑地址包括一个页号和在该页的偏移量。在分页中,由处理器硬件完成逻辑地址到物理地址的转换,处理器知道如何访问页表。
为了使分页的方案更加方便,页和页框的大小必须是2的幂,以便容易地表示出相对地址。
总之,简单的分页技术,内存被分为许多大小相等页很小地页框,每个进程被划分为同样大小的页;较小的进程需要较少的页,较大的需要较多;当一个进程被装入时,它的所有页都被装入到可用页框中,并建立一个页表。
分段
分段技术的逻辑地址分为段号和偏移量。
编译器会把程序和数据指定到不同的段,每个进程都有一个段表,系统也会维护一个内存中的空间块列表。没有内部碎片,有外部碎片。
总之,简单分段技术,进程被划分成许多段,段的大小不需要相等,而内存没有被划分,当进程被调入时,多有段都被装入内存,并建立一个段表。
安全问题
缓冲区溢出攻击
缓冲区溢出,也称为内存越界:输入到一个缓冲区或者数据保存区的数据量超过了其容量,从而导致覆盖了其他的信息的一种状况。
预防策略:
- 编译时防御系统:强化系统以抵制新程序中的恶意攻击。
- 运行时防御系统:检测并中止现有程序中的恶意攻击。