这篇文章主要介绍计算机的体系结构,内存的分层体系,操作系统的内存管理,地址空间和地址生成等内容。
CPU:主要完成了对整个程序或软件的执行的控制。
内存:主要是放置了程序的代码和它所处理的数据。
外设:各种外部设备配合程序更好的完成工作。
计算机内存包含多个层次,包括 CPU 寄存器、cache 和主存(物理内存)、硬盘(虚拟内存)。硬盘用于保存持久化数据。
操作系统会根据需要将数据从主存中放到硬盘中,以便管理数据的容量和提高运行效率。
操作系统的内存管理到底要做什么事情呢?它有如下几个重要的目标。
在这张图中,操作系统将进程 P1、P2、P3 和 P4 的必要数据放在主存中(进程 P1 优先级最高,所有数据都在主存中),暂时不需要访问的数据(进程 P4/P2/P3 的一部分数据)临时存放在磁盘上。
从上图中,也可以看出进程(我们的程序)属于逻辑地址空间,主存和磁盘的内存空间属于物理内存空间。
内存管理的实现高度依赖于硬件:
- 必须知道内存架构(与计算机存储架构紧耦合)
- MMU(内存管理单元):硬件组件负责处理 CPU 的内存访问请求
物理地址空间就是内存条和硬盘的空间,它的管理和控制由硬件来完成的。
逻辑地址空间就是一个运行的程序所拥有的的内存空间,是一种一维的线性地址空间(这种设计可以使得应用程序很容易的进行数据访问操作)。
逻辑地址空间的设计使得数据访问更加方便的「其中一个原因」就是:
逻辑地址空间是一维的线性地址空间,即内存地址在逻辑上是连续的。这种设计使得程序可以使用简单的地址计算来访问数据,而不需要考虑数据在内存中的实际物理位置。这样,程序员可以通过 使用相对地址来访问数据,而不需要关注数据的具体位置。
一个运行的程序所访问的逻辑地址空间,最终都会对应着物理地址空间中的某一位置,可能放在主存中、也可能放在硬盘中。物理地址空间和逻辑地址空间通过映射关系对应起来(映射关系由操作系统进行有效地管理)。
下图展示了逻辑地址的生成过程。
逻辑地址生成的过程可以在编译器、链接器和加载器等工具的协同作用下完成,操作系统通常不需要干预该过程。这样的设计使得程序员可以方便地使用符号和逻辑地址进行开发,而无需关心实际的物理地址和内存布局。
下图展示了物理地址的生成过程。
物理地址的生成过程是由操作系统的内存管理单元(MMU)来完成的。MMU 负责将逻辑地址转换为物理地址,使得程序能够正确地访问内存。
需要注意的是,物理地址生成的过程是 在程序运行时 由硬件执行的,而不是编译、链接或加载阶段进行的。操作系统会在程序加载到内存时设置好页表,并将页表的基地址告诉 MMU,以便进行地址转换。这样,程序在运行过程中,无需关心物理地址的生成和管理,而是通过逻辑地址进行访问。
为了加快地址转换的速度,操作系统会将逻辑地址到物理地址的映射关系存储在内存中,并由 CPU 进行缓存。
具体来说,当 CPU 首次访问某个逻辑地址时,MMU 会根据页表将逻辑地址转换为物理地址,并将该映射关系存储在一个特殊的高速缓存中,称为转换后备缓冲器(Translation Lookaside Buffer,简称 TLB)。TLB 是一种硬件缓存,用于临时存储逻辑地址到物理地址的映射关系。
当程序再次访问相同的逻辑地址时,CPU 会首先检查 TLB 中是否存在该映射关系:
- 如果存在,则可以直接从 TLB 中获取物理地址,从而避免了访问内存的开销;
- 如果 TLB 中没有找到对应的映射关系,则需要通过页表来进行地址转换(上述序号 2 和 3),并将新的映射关系存储到 TLB 中,以便下次访问时可以直接使用。
为了避免应用程序相互访问彼此的地址空间,操作系统提供了独立的地址空间,将它们隔离,以保护应用程序免受破坏。
地址安全检查使应用程序在内存中正常执行,同时保证在内存中不同的应用程序之间不会相互破坏。
参考资料: