【操作系统内存管理(基本概念)】

系列文章目录

1.《带你深挖计算机底层逻辑,打通你计算机基础知识的任督二脉》
2.《深度学习计算机底层原理,深度剖析存储器》
3.《基于内存全面理解高速缓冲存储器》
4.《深度学习计算机指令系统,彻底搞懂指令十大寻址方式》
5.《降维打击,带你深度学习CPU(上)》
6.《深度学习CPU(番外篇)——虚拟内存》


文章目录

  • 系列文章目录
  • 前言
  • 一、内存管理的基本原理
  • 二、进程的内存映像
  • 总结

前言

        内存管理是操作系统最重要最复杂的内容之一,虽然计算机硬件技术在飞速发展,内存容量也在不断扩大,但是仍然不可能将所有的用户进程都全部放入主存,因此操作系统必须对内存空间进行合理的划分和有效的动态分配,操作系统对内存的的划分和动态分配就是内存管理。


一、内存管理的基本原理

1.内存管理的功能

  • 内存空间的分配与回收:由操作系统完成存储空间的分配和管理,使得程序员摆脱存储分配的麻烦,提高编程效率。
  • 地址转换:在多道程序环境下,程序中的逻辑地址与物理地址不可能一致,因此存储空间必须提供地址变换功能,将逻辑地址转换成为物理地址。
  • 内存空间的扩充:利用虚拟技术或者自动覆盖技术从逻辑上扩充内存。
  • 内存共享:允许多个进程访问内存的同一部分
  • 存储保护:各个进程在各自的内存空间上运行,互不干扰。

2.程序的链接与装入

        我们创建一个进程首先要将程序装入内存(进程使程序得抽象,程序的一次活动就叫做进程),但是程序员通过高级语言所写出来的程序(存放在文件当中)并不在内存当中,而且也无法直接装入内存,因为计算机是无法识别高级语言的。所以这个时候就必须将我们所写的程序经过一定的处理,形成计算机可识别的二进制得可执行文件,这个时候,我们所写的程序才可以装入内存。这些处理需要以下步骤。

  • 预处理:将文件的头文件,宏定义全部展开。
  • 编译:将高级语言转换为汇编语言。
  • 汇编:将汇编语言转换为计算机可识别的二进制的目标文件。
  • 链接:将多个模块的文件进行粘合,将库函数等不在原本的文件当中定义的文件与原来的文件进行合并。这时生成可执行文件。
  • 装入:此时可以将可执行文件装入内存。

注释:这里的编译、链接、装入过程复杂,日后我会专门出一个专题来讲述编译、链接这部分的内容,今天在这里就不做过多的讲解了。

3.逻辑地址与物理地址

        程序经过编译后,他的每个目标模块都是从0号单元开始编址,这称为该目标模块的相对地址(逻辑地址),当链接程序将各个模块链接成为一个完整的可执行目标程序时,链接程序顺序依次按照各个模块的相对地址构成统一的从0号单元开始编址的逻辑地址空间(虚拟地址空间)。

        也就是说进程在运行的时候,我们所看到的和使用的地址全部都是逻辑地址,用户程序和程序员只需要知道逻辑地址,而内存管理的机制对用户完全是透明的,不同的进程可以拥有相同的逻辑地址,因为这些相同的逻辑地址可以映射到不同的内存空间去。

        物理地址空间是指内存中物理单元的集合,它是地址转换的最终地址,进程在运行时执行指令和访问数据的时候都必须通过物理地址从内存中存取,当装入程序将可执行文件装入内存中的时候必须通过地址变换将逻辑地址变换成为物理地址才能够顺利地将文件装入内存,这个过程称为地址重定位。

        操作系统通过内存管理部件将进程所使用的逻辑地址转换为物理地址,进程在执行的时候使用的是虚拟内存空间当中的地址,而操作系统必须通过一定的硬件配合将虚拟地址转换为物理地址,逻辑地址是通过页表映射到物理内存的,而页表则是由操作系统维护并被处理器使用。

注释:页表这里涉及到了虚拟内存的知识,各位小伙伴们如果有对于虚拟内存不太理解的话,可以参考我的上一篇文章《深度学习CPU(番外篇)——虚拟内存》

原文链接:http://t.csdn.cn/sjiRL


二、进程的内存映像

1.概述

        我们要知道一个程序要想要执行的话,必须将其调入内存,而在程序调入内存后就会形成一个进程,因为进程就是程序的一次活动,或者说进程本身就是程序的抽象。当一个程序调入内存的时候,就形成了进程的内存映像,一个进程的内存映像有以下几个要素。

  • 代码段:代码段(程序的二进制代码),它用于存放进程的指令,既然是存放指令的段,那么说明它是只读代码段。
  • 数据段:包括全局变量和静态变量,及程序运行时候的加工对象。
  • 进程控制块:操作系统是通过进程控制块来控制进程的,进程控制块当中存放着一个进程最重要最核心的信息,操作系统通过这些信息来对一个进程进行创建、销毁等一系列的操作,注意所谓的进程控制块其实就是有若干的指令和数据组成数据块,并且这种数据块是常驻内存的,内存专门为进程控制块开辟一块缓冲区来专门存放这些进程控制块,这些缓冲区具有一定的数据结构,来对这些进程控制块进行管理。
  • 堆:用来存放动态分配的变量,通过调用malloc函数动态地向该地址分配空间。
  • 栈:用来实现函数调用,从用户的最大地址空间开始分配向低地址方向增长。
操作系统内核区(用户不可见)
用户栈(运行时创建)
共享库的存储映射区
动态生成的堆(运行时由malloc创建)
读/写数据段
只读代码段
未使用区

注释:上图是进程在内存当中的一个概念图,注意内存当中的每个物理块都有相应的地址(上图并未标出),栈区会有一个栈指针来对栈区进行维护。

2.内存保护

        确保每个进程都有一个单独的内存空间,内存分配前,需要保护操作系统不受用户进程的影响,同时保护该进程不受其他进程的影响,内存保护可以采取两种方法。

        1)上下限寄存器:

        在CPU中设置一对上下限寄存器,存放程序在内存中的上限和下限地址,每当CPU要访问一个地址的时候都要分别和两个寄存器的值相比,判断有无越界。

        2)采用重定位寄存器和界地址寄存器:

        重定位寄存器又称为基地址寄存器,界地址寄存器又称为限长寄存器,重定位寄存器包含最小的物理地址,界地址寄存器包含逻辑地址的最大值,内存管理机构动态地将逻辑地址与界地址寄存器进行比较,若没有发生越界,逻辑地址则加上重定位寄存器中的物理地址以后映射成为物理地址,再送交给内存单元。

        注意:重定位寄存器是用来加的,逻辑地址加上重定位寄存器中的物理地址以后就能得到物理地址,界地址寄存器是用来比的,通过比较界地址寄存器中的逻辑地址最大值来判断是否越界。

        加载重定位寄存器和界地址寄存器时必须拥有特权指令才可以,只有操作系统内核才可以加载这两个存储器,只有操作系统才可以修改这两个寄存器的值,而用户是不可以修改的。

        在这里还要再强调一下,不管是之前的上下限寄存器还是现在的重定位寄存器和界地址寄存器都是设置在CPU当中的,也就是内存的保护是通过CPU来实现的,可能会有小伙伴会问为什么重定位寄存器当中的物理地址加上逻辑地址就可以得出真实的物理地址了呢?这里要涉及到CPU的一个重要部件就是ALU算术逻辑单元,这是CPU当中专门用于计算的单元,至于他是怎么算出来的,我们不需要知道。

3.内存共享

        并不是所有的进程内存空间都适合共享,只有那些只读的区域才适合共享,可重入代码又称为纯代码,是一种允许多个进程访问但是不允许多个进程修改的代码,但在实际执行的时候,也可以为每个进程配备局部数据区,将在执行过程中需要修改的数据复制到该区域,这样程序在执行的时候只需要对该私有区域进行修改即可,并不需要去改变共享的代码。

4.内存分配与回收

        存储管理方式随着操作系统的发展而发展,在操作系统由单道向多道发展的时候,存储管理方式便由单一连续分配发展为固定分区分配,为了能跟好的适应不同大小的程序要求,又从固定分区分配发展到动态分区分配,又为了能够更好地提高内存利用率,进而从连续分配方式发展到离散分配方式——也是存储管理。


三、覆盖与交换

覆盖与交换是多道程序环境下用来扩充内存的两种方法。

1.覆盖

        在早期的计算机系统中,内存容量很小,虽然主存中只存放一道用户程序,但存空间放不下用户进程的现象也经常发生,这一矛盾可以使用覆盖来解决。

        覆盖的基本思想如下,由于程序运行时并非任何时候都要访问程序及数据的各个部分(尤其是大程序),因此可把用户空间分成一个固定区和若干覆盖区,将经常活跃的部分(CPU经常访问的主存中的数据)放在固定区,其余部分按照调用关系分段,即将要访问到的数据放到覆盖区,其余放入外存,在需要调用之前再将其调入覆盖区,替换覆盖区中原有的片段。

        这样子即使程序没有全部装入内存的时候也可以执行程序,并且内存当中更新的地方只有覆盖区,固定区当中的代码是常驻内存的。但是当程序的代码量大于内存量的时候,程序时无法执行的。

2.交换

        交换顾名思义就是将正在等待CPU执行的程序从内存当中调到外存中去,将内存空间腾出来,这个过程叫做换出,将再外存当中准备好的程序从外存当中调入内存这个过程叫做换入。

        例如,一个CPU采用时间片轮转制度调度算法的多道程序环境,时间片一到就将刚刚执行的程序换出,将另外一个进程换入刚刚释放的内存空间,同时,CPU调度器可以将时间片分配给在内存中的其他进程,每个进程用完时间片以后都要与其他进程交换,理论上只要交换的速度足够的快,总有进程可以在内存中运行。

        关于交换,还是要注意一下几个问题:

  • 交换需要备份存储,通常是磁盘,它必须足够大,并提供对这些内存映像的直接访问。
  • 为了有效地使用CPU,需要使每个进程的执行时间比交换时间长。
  • 若换出进程,则必须确保该进程完全处于空闲等待状态。
  • 交换空间通常作为磁盘的一整块,且独立于文件系统。
  • 交换通常要在内存空间吃紧的时候开始,在系统负荷降低时就暂停。

注意:对于扩充内存现代的操作系统时通过虚拟内存来实现的,而覆盖技术早就已经成为了历史,不过交换技术还是比较有生命力的。


总结

        今天为大家详细地介绍了操作系统当中的内存管理的基本概念,下一篇文章就该带大家领略一下内存空间分配的三大方式,以及页式存储管理、段式存储管理、页段式存储管理等重要内容,我们不见不散。


你的支持就是我最大的动力,请问你学会了吗

你可能感兴趣的:(计算机底层原理,windows,硬件工程)