文章目录

操作系统的内存管理中段式管理与页式管理并不是对立的,他们结合起来内存的使用效率会更高。他们都属于离散分配内存的管理方式,当然还有连续型内存分配的管理方式, 连续分配是指为一个用户程序分配连续的内存空间。连续分配有单一连续存储管理和分区式储管理两种方式。

1、连续分配内存

1.1、单一连续存储管理

采用这种管理方案时,内存被分成两个区域,一个是系统区域,仅供操作系统使用,可以驻留在内存的低地址部分,也可以驻留在高地址部分;另一个是用户区,它是除系统区以外的全部内存区域,这部分区域是提供给用户使用的区域,任何时刻主存储器中最多只有一个作业。所以,单一连续区存储管理只适用于单用户的情况。cpu要么处于运行状态、要么处于空闲状态。

1.2、分区式存储管理

支持多个程序并发执行,引入了分区式存储管理。分区式存储管理是把内存分为一些大小相等或不等的分区,操作系统占用其中一个分区,其余的分区由应用程序使用,每个应用程序占用一个或几个分区。分区式存储管理虽然可以支持并发,但难以进行内存分区的共享。分区式管理被分为了固定分配和动态分配。 固定式分区的特点是把内存划分为若干个固定大小的连续分区。易产生内部碎片。 动态分区可以在装入时按其要求进行动态分配,但是易于产生外部碎片,常用的算法有最佳、最坏、最先适配法。

连续分配都是直接分配物理地址,如果可以将进程的各部分分散的装入在内存中,这样就减少了碎片的产生,提高了内存的效率。由此引出了逻辑地址和离散型存储管理。

2、离散型存储管理

2.1页式管理

将各进程的虚拟空间划分为若干长度相等的页。内存空间按页的大小建立页表。

 位移量的位数决定页的大小,通过页表映射找到页对应的内存块。

优点:没有外碎片,每个内碎片不超过页的大小。

缺点:程序全部装入内存,要求有相应的硬件支持(硬件产生缺页中断)。

 2.2段式管理

  将程序按内容或过程函数关系分成段,例如程序段、数据段。。。以段为单位分配内存,通过地址映射机制,将段式虚拟地址转换成实际内存物理地址。段的长度由相应的逻辑信息组的长度决定,因而各段长度不等。

逻辑地址得到段号、段内地址,再根据段号和段表求出基址,再由基址+段内地址即可得物理地址。

优点:可以分别编写和编译,可以针对不同类型的段采取不同的保护,可以按段为单位进行共享,包括通过动态链接进行代码共享,每次交换的是一组相对完整的逻辑信息。

缺点:会产生外部碎片,进程必须全部装入内存。

2.3段页式管理

内存以段为单位划分,每个段又划分成若干个页。需要有一张段表管理内存分配与释放、缺段处理。同时每个段还需要一张页表把段中的虚页转换成内存中的实际页面。页表也需要有实现缺页中断处理和页面保护等功能的表项。

                            地址结构:** 段号+段内页号+页内地址(位移量)
  • 第一次访问段表,得到页表起始地址;
  • 第二次访问页表,得到物理页号;
  • 第三次将物理页号与页内位移组合,得到物理地址。

优点:有段。页管理的优点。

缺点:复杂度提高。

3、MMU内存管理单元

如果查这段表与页表的操作全部由软件来实现的话就要浪费很多时间了,因此计算机将查表的操作交给硬件来完成,只要从用户程序那里得到CS:IP,硬件会自动得到该逻辑地址对应的物理地址的,这个硬件就是MMU

总结

为了在多进程环境下,使得进程之间的内存地址不受影响,相互隔离,于是操作系统就为每个进程独立分配一套虚拟地址空间,每个程序只关心自己的虚拟地址就可以,实际上大家的虚拟地址都是一样的,但分布到物理地址内存是不一样的。作为程序,也不用关心物理地址的事情。 每个进程都有自己的虚拟空间,而物理内存只有一个,所以当启用了大量的进程,物理内存必然会很紧张,于是操作系统会通过内存交换技术,把不常使用的内存暂时存放到硬盘(换出),在需要的时候再装载回物理内存(换入)。 那既然有了虚拟地址空间,那必然要把虚拟地址「映射」到物理地址,这个事情通常由操作系统来维护。那么对于虚拟地址与物理地址的映射关系,可以有分段和分页的方式,同时两者结合都是可以的。 内存分段是根据程序的逻辑角度,分成了栈段、堆段、数据段、代码段等,这样可以分离出不同属性的段,同时是一块连续的空间。但是每个段的大小都不是统一的,这就会导致内存碎片和内存交换效率低的问题。于是,就出现了内存分页,把虚拟空间和物理空间分成大小固定的页,如在 Linux 系统中,每一页的大小为 4KB。由于分了页后,就不会产生细小的内存碎片。同时在内存交换的时候,写入硬盘也就一个页或几个页,这就大大提高了内存交换的效率。 再来,为了解决简单分页产生的页表过大的问题,就有了多级页表,它解决了空间上的问题,但这就会导致 CPU 在寻址的过程中,需要有很多层表参与,加大了时间上的开销。于是根据程序的局部性原理,在 CPU 芯片中加入了 TLB,负责缓存最近常被访问的页表项,大大提高了地址的转换速度。 Linux 系统主要采用了分页管理,但是由于 Intel 处理器的发展史,Linux 系统无法避免分段管理。于是 Linux 就把所有段的基地址设为 0,也就意味着所有程序的地址空间都是线性地址空间(虚拟地址),相当于屏蔽了 CPU 逻辑地址的概念,所以段只被用于访问控制和内存保护。另外,Linxu 系统中虚拟空间分布可分为用户态和内核态两部分,其中用户态的分布:代码段、全局变量、BSS、函数栈、堆内存、映射区。