内存管理:内存的分配与回收

  • 1 内存的分配与回收
    • 1.1 连续分配
      • 1.1.1 单一连续分配
      • 1.1.2 固定分区分配
      • 1.1.3 动态分区分配
    • 1.2 非连续分配
      • 1.2.1 分段存储管理
        • 1.2.1.1 地址变换机构
        • 1.2.1.2 段的共享
      • 1.2.2 分页存储管理
        • 1.2.2.1 基本地址变换机构
        • 1.2.2.2 具有快表的地址变换机构
        • 1.2.2.3 两级页表
      • 1.2.3 段页式存储管理
      • 1.2.4 分段与分页的对比

声明:大部分截图来自王道考研操作系统,部分图已标明出处,侵删


知识点概览

1 内存的分配与回收

进程3应该被分配到哪里?如何进行分配?
下图来自王道考研操作系统

1.1 连续分配

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

1.1.1 单一连续分配

用户区存放用户进程相关数据
内存中只能有一道用户程序,该程序独占整个用户区

下图来自王道考研操作系统

1.1.2 固定分区分配

在早期多道程序系统中,整个用户空间划分为若干个固定大小的分区,在每个分区中只装入一道作业
下图来自王道考研操作系统

1.1.3 动态分区分配

不会预先划分内存分区,而在进程装入内存时,根据进程大小动态建立分区,使得分区的大小为进程的大小

1.系统要用什么样的数据结构记录内存的使用情况
记录哪些地址被占用了?哪些没有被占用?

下图来自王道考研操作系统

(1)空闲分区表

(2)空闲分区链

2.当很多个空闲分区都能满足需求时,应该选择哪个分区进行分配?
利用动态分区分配算法

常见的动态分区分配算法:

1.首次适应算法(从头到尾找最合适的空闲分区)
基本思想:查找空闲分区表/链,每次都从低地址开始查找,找到第一个满足大小的空闲分区,即要进入内存的进程需要的分区大小 ≤ 某空闲分区大小
2.邻近适应算法(每次从上次查找结束的位置开始查找)
首次适应算法每次都是从低地址(空闲分区表/链的表头/链头)开始查找,开销太大
基本思想:每次分配内存时都从上次查找结束的位置开始查找空闲分区表/链,找到第一个满足大小的空闲分区
3.最佳适应算法(优先使用更小的空闲分区,保留更多大分区)
基本思想:先找到并使用第一个能满足进程的最小的空闲分区
4.最坏适应算法(优先使用更大的空闲分区,防止太小的不可用碎片)
解决最佳适应算法中会导致产生太多外部碎片的问题,因为先用的小分区,但这小分区中又可能用不完
基本思想:先找到并使用第一个能满足进程的最大的空闲分区

3.如何进行分区回收操作?

直接修改空闲分区表中的分区大小和起始地址
进程所处位置不同,对应回收后的情况也不同
也可能导致多个分区合并后,分区的个数减少,需要删除被合并的原分区
也可能导致分区增加

外部碎片:内存中某些空闲区太小而难以利用
可以通过紧凑技术解决外部碎片问题,也就是将进程都移动到一起


内部碎片:分配给某进程的内存区域中有些部分没有用上

1.2 非连续分配

非连续分配:为用户进程分配的可以是分散的内存空间

1.2.1 分段存储管理

在分段存储管理方式中,作业的地址空间被划分为若干个段(大小不一定相等),每个段定义了一组逻辑信息–摘自:基本分段存储管理方式

段是信息的逻辑单位。分段的主要目的是更好地满足用户需求。分段对用户是可见的,用户编程时需要显式地给出段名
段的长度不固定由用户编写的程序决定


1.2.1.1 地址变换机构


注意:段内地址要判断是否越界,因为段的大小不等,不判断无法知道是否越界。而分页中页的大小固定,无需判断页内地址是否越界

1.2.1.2 段的共享

不能修改的代码称为纯代码或可重入代码(不属于临界资源)这样的代码可以共享,不能修改的数据也可以共享。能够被修改的代码和数据不能被共享


为什么分页无法实现共享?
因为如果页内某一部分是允许共享的,而另一部分不允许共享,会出现矛盾,到底这个页是否可以共享
而分段中的共享段中的数据可以全部共享

1.2.2 分页存储管理

分页目的:希望内存的使用能尽量避免碎片产生
分页思想:把主存空间划分为大小相等的且固定的块(相对较小),作为主存的基本单位
把每个进程也以块为单位进行划分,进程在执行时,以块为单位逐个申请主存中的空间

进程中的块称为:页 / 页面(Page)
内存中的块称为:页框 / 页帧 / 内存块 / 物理块 / 物理页面(Page Frame)
外存中的块称为:块 / 盘块(Block)

分页存储管理是将一个进程的逻辑地址空间分成若干个大小相等的片,称为页面或页
把内存空间分成与页面相同大小的若干个存储块,称为(物理)块或页框(frame)
在为进程分配内存时,以块为单位将进程中的若干个页分别装入到多个可以不相邻接的物理块中–摘自:基本分页存储管理方式

页是信息的物理单位。分页的主要目的是为了实现离散分配,提高内存利用率。分页仅仅是系统管理上的需要,完全是系统行为,对用户不可见
页的大小固定由系统决定


逻辑地址A到物理地址的转换

  1. 确定A对应的页号P
    (页号 = 逻辑地址/页面长度) 结果取整数部分,上图中页面长度为4KB
  2. 找到P号页面在内存中的起始地址
    (第 P 号内存块的起始地址 = P × 内存块大小)
    上一个内存块的末尾地址是下一个内存块的起始地址,而内存块从0开始,所以得到上面的结论
  3. 逻辑地址A对应的物理地址 = 内存块的起始地址 + 页内偏移量W
    (页内偏移量 = 逻辑地址 % 页面长度) 结果取余数部分

分页存储管理的逻辑地址结构(逻辑地址空间中)

0 ~ 11共12位,占用的存储空间大小为 212=42^{12}=4212=4 KB,所以一个页面大小为4KB
每位都有0和1两种状态,所以20位共有 2202^{20}220 种结果,每种结果对应一个页面,所以20位对应最多 2202^{20}220 个页面

页表项(页表中)

0 ~ 23共24位,24/8=3B,所以一个页表项大小为3B

物理地址结构(内存中)

假设物理内存为4GB,页面大小为4KB,则每个页表项至少应该为多少字节?

  1. 页面大小 = 内存块大小 = 4KB = 4096B =2122^{12}212 Byte
  2. 4GB的内存总共会被分为 232/212=2202^{32}/2^{12}=2^{20}232/212=220 个内存块
    (内存总大小/内存中每个内存块的大小 = 内存块个数)
  3. 内存块号范围 000 ~ 220−12^{20}-1220−1(一个内存块对应一个号)
  4. 内存块至少要用 20 bit 来表示
  5. 至少要用 3 Byte 来表示块号(3×8=24 bit > 20bit)

1.2.2.1 基本地址变换机构

通过页表实现从逻辑地址到物理地址转换的硬件机构
需要两次访存

1.2.2.2 具有快表的地址变换机构

快表(TLB)是一种高速缓存(硬件),用于存放最近访问的页表项(页号+内存块号)的副本,加快地址转换速度.(页表为慢表,在内存中,故访问页表需要访问内存)

快表只存了页表项的一部分副本

下图来自小林coding

情况一:TLB未命中,需要访问页表
如果要查询的页号在TLB中未命中,则下一步查询页表,在页表中命中后得到对应的内存块号,随后将对应内存块的起始地址+页内偏移量得到物理地址,最后由该物理地址访问对应的内存单元(TLB未命中,则需两次访存)

情况二:TLB命中,无需访问页表
如果要查询的页号在TLB中命中,得到对应的内存块号,随后将对应内存块的起始地址+页内偏移量得到物理地址,最后由该物理地址访问对应的内存单元(TLB命中,只需一次访存)

1.2.2.3 两级页表

单级页表出现的问题
问题一:页表必须连续存放,当页表很大时,需要占用很多连续的页框
(K号页对应页表项的存放位置 = 页表起始地址+K*4KB,K必须连续取才能找到任一内存块,所以导致页表必须连续存放)

问题二:没有必要把整个页表都常驻内存,因为一段时间内可能只需访问某几个页面(局部性原理)
可以在需要用到的时候才将页面调入内存(虚拟存储技术),可以给页表项增加一个标志位,代表某页面是否已经调入内存。若想要访问的页面不在内存中,则产生缺页中断(属于内中断),然后将目标页面从外存调入内存

两级页表
下图来自王道考研操作系统

下图来自小林coding

31~22位共10bit,每个bit有两种状态,所以10位共有 2102^{10}210 种状态

大概描述一下过程
例如:通过一级页表中的内存块号3,找到了整个二级页表0#(在内存中的第3个内存块中),通过第3个内存块的起始地址+某个偏移量得到某个内存块号,由此找到最终要访问的内存块,再获取该内存块的起始地址+页内偏移量,最终得到要访问的内存单元的物理地址

多级页表

1.2.3 段页式存储管理

1.先将程序划分为多个有逻辑意义的段,也就是前⾯提到的分段机制;
2.接着再把每个段划分为多个⻚,也就是对分段划分出来的连续空间,再划分固定⼤⼩的⻚;–摘自:小林coding

下图来自小林coding


1.2.4 分段与分页的对比

内存管理:内存的分配与回收相关推荐

  1. 【Linux 内核 内存管理】物理分配页 ⑧ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | 获取首选内存区域 | 异步回收内存页 | 最低水线也分配 | 直接分配 )

    文章目录 一.获取首选内存区域 二.异步回收内存页 三.最低水线也分配 四.直接分配内存 在 [Linux 内核 内存管理]物理分配页 ② ( __alloc_pages_nodemask 函数参数分 ...

  2. 【Linux 内核 内存管理】物理分配页 ⑨ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | retry 标号代码分析 )

    文章目录 一.retry 标号代码分析 二.retry 标号完整代码 在 [Linux 内核 内存管理]物理分配页 ② ( __alloc_pages_nodemask 函数参数分析 | __allo ...

  3. 内存管理-动态分区分配方式模拟

    内存管理 - 动态分区分配方式模拟 操作系统第二次课程作业 - 动态分区分配方式模拟 项目需求 假设初始态下,可用内存空间为640K,并有下列请求序列,请分别用首次适应算法和最佳适应算法进行内存块的分 ...

  4. Android进阶——性能优化之内存管理机制和垃圾采集回收机制(六)

    文章大纲 引言 一.内存泄漏和内存溢出概述 二.Java运行时内存模型 1.线程私有数据区 1.1.程序计数器PC 1.2.虚拟机栈 1.3 本地方法栈 2.所有线程共享数据区 2.1.Java堆 2 ...

  5. 【Linux 内核 内存管理】物理分配页 ⑦ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | 判断页阶数 | 读取 mems_allowed | 分配标志位转换 )

    文章目录 一.__alloc_pages_slowpath 慢速路径调用函数 二.判断页阶数 三.读取进程 mems_allowed 成员 四.分配标志位转换 五.__alloc_pages_slow ...

  6. LwIP 之五 详解动态内存管理 内存堆(mem.c/h)

    写在前面   目前网上有很多介绍LwIP内存的文章,但是绝大多数都不够详细,甚至很多介绍都是错误的!无论是代码的说明还是给出的图例,都欠佳!下面就从源代码,到图例详细进行说明.   目前,网络上多数文 ...

  7. 内存管理-内存池的实现

    内存池的实现 1 前言 2 内存池的原理 2.1 内存利用链表进行管理 2.2 分配固定大小 2.3 按块进行内存管理 3 内存池的实现 3.1 内存池的创建 3.2 内存池的销毁 3.3 内存分配 ...

  8. LwIP 之六 详解动态内存管理 内存池(memp.c/h)

      该文主要是接上一部分LwIP 之 详解动态内存管理 内存堆(mem.c/h),该部分许多内容需要用到上一篇的内容.该部分主要是详细介绍LwIP中的动态内存池.整个内存池的实现相较于内存堆来说,还是 ...

  9. dpdk内存管理——内存初始化

    *说明:本系列博文源代码均来自dpdk17.02* 1.1内存初始化 1.1.1 hugepage技术 hugepage(2M/1G..)相对于普通的page(4K)来说有几个特点: (1) huge ...

  10. 11 操作系统第三章 内存管理 内存的基本知识 内存管理 内存空间扩充 连续分配管理方式

    文章目录 1 内存概念 1.1 内存作用 1.2 逻辑地址VS物理地址 1.3 装入的三种方式 1.3.1 绝对装入 1.3.2 可重定位装入 1.3.3 动态重定位装入 1.4 链接的三种方式 1. ...

最新文章

  1. silverlight 跨域文件位置
  2. 给定下面的java代码_则运行_会产生类型的异常_JavaSE_笔试题_单选选择题
  3. FragmentTabHostUnderLineDemo【FragmentTabHost带下划线】
  4. 数据结构-线性相关代码
  5. 无心剑中译杰克•谢弗《当默多克遇到撒旦》
  6. 字符串匹配之KMP算法
  7. bootstrap 小点
  8. ZooKeeper之ZkClient使用示例
  9. [入门] Delphi XE2 的控件安装方法。
  10. Shiro 常用标签
  11. 《剑指offer》66道算法题合集(java实现)
  12. 连续,可积,存在原函数,变上限积分
  13. MySQL的金科玉律:“不要使用SELECT *”
  14. 【论文阅读】GPT系列论文详解
  15. 【强化学习】逆强化学习概念
  16. ios使用lua详解
  17. 大学生考华为ICT认证,从哪个级别开始
  18. 计算机应用最普遍的汉字字符编码是什么,计算机中目前最普遍使用的汉字字符编码是什么...
  19. 在Ubuntu18.04中安装谷歌地球Google Earth
  20. 海信电视云账号连不上服务器,海信云账号如何使用?图文教程详解

热门文章

  1. 衡量线性回归法的指标:MSE, RMSE和MAE
  2. 解决ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.
  3. 《纽约时报》最新撰文:AI已成必需品,机器人记者正在崛起
  4. 为什么你当下的生活如此无聊——10个残酷而诚恳的原因
  5. win7 ipv6的默认网关怎么填
  6. 实现淘宝搜索后界面显示商品列表效果
  7. DLL巧妙的绕过被VMP壳HOOK的ZwProtectVirtualMemory
  8. Codeup墓地-1031
  9. html实现经典打方块小游戏
  10. 怎么把图片分辨率提高?图片分辨率不够怎么办?