zoukankan      html  css  js  c++  java
  • 内存管理

    内存管理

    内存基本知识

    什么是内存,有何作用

    • 内存:存放数据
    • 程序执行前需要先放到内存中才能被CPU处理--缓和CPU与硬盘之间的速度矛盾
    • 内存地址,内存单元

    进程运行的基本原理

    指令的工作原理

    • 操作码+若干参数

    逻辑地址vs物理地址

    • 程序经过编译、链接后生成的指令中指明的地址是逻辑地址(相对地址)相对于进程的起始地址而言

    如何实现地址转换

    • 装入的三种方式
    • 绝对装入:在编译时,如果知道程序将放到内存中的那个位置,编译程序将产生绝对地址的目标代码
      • 装入程序按照装入模块中的地址,将程序和数据装入内存
      • 绝对装入只适用于单道程序环境
      • 灵活性差
    • 静态重定位:又称可重定位装入。编译、链接后的装入模块地址都是从0开始的,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。
      • 可根据内存的当前情况,将装入模块装入到内存的适当位置
      • 装入时对地址进行“重定位”,将逻辑地址变换为物理地址(地址变换是在装入时一次完成的)
      • 静态重定位的特点是在一个作业装入内存时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业
      • 运行期间就不能再移动
    • 动态重定位:又称动态运行时装入。编译、连接后的装入模块的地址都是从0开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行。
      • 装入内存后的地址依然是逻辑地址,这种方式需要一个重定位寄存器的支持
      • 采用动态重定位时允许程序在内存中发生移动
      • 并且可将程序分配到不连续的存储区中,在程序运行前只需装入它的部分代码即可运行,然后在程序运行期间,根据需要动态申请分配内存
      • 便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间

    从写程序到程序运行的过程

    • 编辑 -》 编译 -》 链接 -》 装入

    • 编译:由编译程序将用户源代码编译成若干个目标模块(就是把高级语言翻译为机器语言)

    • 链接:由链接程序将编译后形成的一组目标模块,以及所需库函数链接在一起,形成一个完整的装入模块

    • 由装入程序将装入模块装入内存运行

    • 链接的三种方式

    • 静态链接:在程序运行前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件

    • 装入时动态链接:将各目标模块装入内存时,边装入边链接

    • 运行时动态链接:在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享

    内存管理的概念

    内存空间的分配于回收

    • 连续分配:指为用户进程分配的必须是一个连续的内存空间

    连续分配管理方式

    • 单一连续分配

    • 在单一连续分配方式中,内存被分为系统区和用户区。系统区通常位于内存的低地址部分,用于存放操作系统相关的数据;用户区用于存放用户进程相关的数据

      • 内存中只能有一道用户程序,用户程序独占整个用户区空间
      • 优点:实现简单;无外部碎片,可以采用覆盖技术扩充内存,不一定需要采取内存保护
      • 缺点:只能用于单用户、单任务的操作系统中,有内部碎片,存储器利用率极低
    • 固定分区分配:将整个用户空间划分为若干个固定大小的分区,在每个分区只装入一道作业

    • 分区大小相等

      • 缺乏灵活性
      • 适用于一台计算机控制多个相同对象的场合
    • 分区大小不等

      • 增加了灵活性,可以满足不同大小的进程需求。
    • 操作系统需要建立一个数据结构--分区说明表,来实现各个分区的分配与回收。

    • 每个表项对应一个分区,通常按分区大小排列,每个表项包括对应分区的大小、起始地址、状态(是否已分配)

    • 当某用户进程要装入内存时,由操作系统内核程序根据用户程序大小检索该表,从中找到一个能满足大小、未分配的分区,将之分配给该程序,然后修改状态为“已分配”

      • 优点:实现简单,无外部碎片
      • 缺点:当用户程序太大,所有分区都不能满足,会不得不使用覆盖技术,降低性能,会产生内部碎片
    • 动态分区分配

    • 又称可变分区分配:不会预先划分内存分区,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要

      • 系统要用怎样的数据结构记录内存的使用情况
        • 空闲分区表:每个空闲分区对应一个表项。包含区号,分区大小,起始地址等
        • 空闲分区链:每个分区的起始部分和末尾部分分别设置前向指针和后向指针。起始部分处还可记录分区大小等信息
      • 当有很多空闲分区都能满足,如何选择那个分区进行分配
        • 按照一定动态分配算法
      • 如何进行分区的分配和回收
        • 相邻空闲分区合并
    • 内部碎片:分配给某进程的内存区域中,如果有些部分没有用上

    • 外部碎片:是指内存中的某些空闲分区由于太小而难以利用

    • 可以利用紧凑技术来解决外部碎片

    动态分区分配算法

    首次适应算法
    • 算法思想:每次都从低地址开始查找,找到第一个能满足大小的空闲分区
    • 实现原理:空闲分区以地址递增的次序排列,每次分配内存时顺序查找空闲分区链表(空闲分区表),找到大小能满足要求的第一个空闲分区
    最佳适应算法
    • 算法思想:由于动态分区分配是一种连续分配方式,为各进程分配的空间必须是连续的一整片。优先使用更小的空闲区,尽可能多留大片的空闲区
    • 实现原理:空闲分区按照容量递增次序链接。每次分配内存时顺序查找空闲分区链(空闲分区表),找到大小能够满足要求的第一个空闲分区
    • 缺点:每次都选用最小的分区进行分配,会留下越来越多的外部碎片
    最坏适应算法
    • 又称最大适用算法
    • 算法思想:每次分配时优先适用最大的连续空闲区
    • 实现原理:空闲区按容量递减次序链接。每次分配内存时顺序查找空闲分区链表,找到按大小能满足要求的第一个空闲分区
    • 缺点:最先适用大空闲区,当由大进程时,就没有内存分区可用了
    邻近适应算法
    • 算法思想:由首次适应算法演变而来,每次从上次查找结束的位置开始查找

    • 实现原理:空闲分区地址递增次序排列

    非连续分配管理方式

    基本分页存储管理
    • 分页存储:将内存空间分为一个个大小相等的分区,每个分区就是一个页框。每个页框有一个编号

    • 将进程的逻辑地址空间也分为与页框大小相等的一个个部分,每个部分称为一个“页”或“页面”。每个页面也有一个编号

    • 操作系统以页框为单位为各个进程分配内存空间。进程的内阁页面分别放入一个页框中。进程页面与内存的页框有一一对应的关系

      • 页表:为了能知道进程的每个页面在内存中存放的位置,操作系统要为每个进程建立一张页表。
      • 页表通常存在PCB中
      • 一个进程对应一张页表
      • 进程的每个页面对应一个页表项
      • 每个页表项由“页号”和“块号”组成
      • 页表记录进程页面和实际存放的内存块之间的映射关系

    内存空间的扩充

    覆盖技术

    • 用来解决“程序大小超过物理内存总和的问题”
    • 思想:将程序分为多个段(多个模块)。常用的段常驻内存,不常用的段在需要时调入内存
    • 内存分为一个“固定区”和若干个“覆盖区”
    • 需要常驻内存的段放在“固定区”中,调入后就不再调出(除非运行结束)
    • 不常用的段放在“覆盖区”,需要用到时调入内存,用不到时调出内存
    • 必须由程序员声明覆盖结构,操作系统完成自动覆盖。
    • 缺点:对用户不透明,增加了用户编程的负担

    交换技术

    • 思想:内存空间紧张时,系统将内存中的某些进程暂时换出外存,把外存中某些已具备运行条件的进程换入内存(进程在内存与磁盘之间动态调度)
    • 暂时换出外存等待的进程状态为挂起状态
    换出的位置
    • 具有对换功能的操作系统,通常把磁盘空间分为文件区和对换区两部分
    • 文件区用于存放文件,主要追求存储空间的利用率,因此文件区空间管理采用离散分配方式
    • 对换区空间只占磁盘空间的小部分,被换出的进程数据存放在对换区,对换区空间管理主要追求换入换出速度,因此通常对换区采用连续分配方式
    • 对换区的I/O速度比文件区的更快
    什么时候换出
    • 经常发生缺页,内存紧张时
    换出那些进程
    • 可换出优先级低的进程,有的会考虑进程在内存中驻留的时间
    PCB会常驻内存
    • 覆盖是在同一进程或进程中的
    • 交换是在不同进程(或作业)之间的

    虚拟存储技术

    地址转换

    存储保护

    • 保证各进程在自己的内存空间内运行,不会越界访问
    • 在CPU中设置一对上下限寄存器,存放进程的上、下限地址。进程的指令要访问某个地址空间时,CPU检查是否越界
    • 采用重定位寄存器(基址寄存器)和界地址寄存器(限长寄存器)进行越界检查。重定位寄存器中存放的是进程的起始物理地址。界地址寄存器存放的是进程的最大逻辑地址。
  • 相关阅读:
    JAVA学习---JAVA基础元素
    JAVA开发-eclipse打开失败:A Java Runtime Environment(JRE) or Java Development Kit(JDK) must be available……的解决办法
    文章转载---西工大博士生文言文答辩致谢
    python中正则匹配之re模块
    python中random模块的使用
    python中函数的定义及调用
    Python中字符编码及转码
    python中字符串输出格式
    数据库与表的剩余操作
    线程其他相关用法和守护线程
  • 原文地址:https://www.cnblogs.com/li-code/p/11413704.html
Copyright © 2011-2022 走看看