码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【操作系统】内存管理


    文章目录

    • 内存的基础知识
      • 什么是内存
      • 进程的工作原理
        • 指令的工作原理
        • 逻辑地址(相对地址)vs物理地址(绝对地址)
        • 从写程序到程序运行—编译、链接、装入
        • 装入的三种方式
        • 链接的三种方式
    • 什么是内存管理?
      • 内存空间的分配与回收
      • 内存空间的扩展(实现虚拟性)
      • 地址转换
      • 内存保护
    • 覆盖与交换技术
      • 覆盖技术
      • 交换技术
    • 内存的分配与回收
      • 单一连续分配
      • 固定分区分配
      • 动态分区分配(可变分区分配)
      • 内部碎片与外部碎片
    • 动态分区分配算法
      • 首次适应算法
      • 最佳适应算法
      • 最坏(大)适应算法
      • 临近适应算法
      • 四种算法归纳比较
    • 分页存储
      • 基本分页存储管理的思想
      • 分页存储管理的重要概念
      • 如何实现地址的转换
        • 如何计算页号和页偏移量
        • 分页存储的逻辑结构
        • 如何知道页面在内存中的起始地址?
    • 分页存储管理的基本地址变换结构
      • 页表寄存器
      • 对页表项大小的进一步讨论
    • 快表的地址变换结构
      • 什么是快表
      • 局部性原理引入快表机制
      • 引入快表后,地址的变换过程
      • 基本地址变换与快表地址变换的比较
    • 二级页表
      • 为什么引入二级页表?
      • 二级页表的原理和地址结构
      • 如何实现二级页表的地址变换?
      • 几个小细节
    • 基本分段存储管理
      • 什么是分段?
      • 分段的逻辑地址结构
      • 段表
      • 地址变换
      • 分段、分页管理的对比
        • 分段实现信息共享共享
        • 为什么分页不方便实现信息共享和保护?
    • 段页式存储管理
      • 分页、分段的优缺点分析
      • 分段+分页=段页式管理
        • 段页式管理的逻辑地址结构
        • 段页式存储的段表、页表
      • 段页式管理的地址转换过程
    • 虚拟内存
      • 传统存储管理的特征、缺点
      • 局部性原理
      • 虚拟内存的定义和特征
      • 如何实现虚拟内存技术
    • 请求分页管理方式
      • 页表机制—请求页表与基本页表的区别
      • 缺页中断机构
      • 地址变换机构
    • 页面置换算法
      • 最佳置换算法—OPT
      • 先进先出置换算法—FIFO
      • 最近最久未使用置换算法—LRU
      • 时钟置换算法—CLOCK
      • 改造型时钟置换算法
    • 页面分配策略
      • 驻留集
      • 页面分配、置换策略
        • 固定分配局部置换、可变分配局部置换、可变分配全局置换
      • 何时调入页面?
      • 从何处调页?
      • 抖动(颠簸)现象
      • 工作集

    本系列参考王道考研-操作系统以及博主@BitHachi

    内存的基础知识

    什么是内存

    在这里插入图片描述
    在这里插入图片描述

    因为cpu的处理速度很快,而外存的读取速度又很慢,所以我们就需要先加载到内存中,内存的读取速度比外存要快得多,如此实现更高效的处理

    在这里插入图片描述

    进程的工作原理

    指令的工作原理

    从X=X+1大致看一下指令的执行过程

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    指令的工作基于地址。每个地址对应一个数据的存储单元。

    逻辑地址(相对地址)vs物理地址(绝对地址)

    在这里插入图片描述

    从写程序到程序运行—编译、链接、装入

    在这里插入图片描述

    不修改装入模块中的指令地址就直接装入内存的话:

    在这里插入图片描述
    在这里插入图片描述

    也就是说只有当装入模块使用的内存从#0开始时,不修改装入模块中的指令地址才能行得通

    装入的三种方式

    • 绝对装入 在这里插入图片描述

      这也叫就意味着这个程序换一台就不能运行了,此方式灵活性较低

    • 静态重定位
      在这里插入图片描述

    • 动态重定位
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    链接的三种方式

    首先我们了解一下什么是链接:

    程序的链接阶段主要做了以下几件事:

    1. 符号解析:将各个模块中使用的符号(函数名、全局变量名等)替换为实际的地址。例如如果模块A调用模块B的函数foo(),那么链接器会找到模块B中foo()的实际地址,并在模块A的调用指令中填入那个地址。
    2. 重定位:修改程序中用到的地址,以适应最终的加载地址。例如模块A中有一个data段从0x1000开始,模块B有一个data段从0x2000开始。那么链接器可能决定模块A加载到0x5000,模块B加载到0x6000。这时候链接器需要修改模块A中所有0x1000的地址为0x5000,修改模块B中的0x2000为0x6000。
    3. 解决外部符号:如果有模块调用了未定义的外部符号(例如调用了标准库函数),那么链接器需要链接适当的库来满足这些外部需求。
    4. 重复符号处理:如果有多个模块定义了相同的符号,链接器需要决定使用哪一个,并可能报错。
    5. 生成输出文件:链接的最后,链接器会将所有输入的目标文件组合成一个输出文件(可执行文件或共享库)。这个输出文件就包含了所有符号解析、重定位等处理的结果。

    所以简单来说,链接的作用是将多个目标模块组合为一个连贯的程序,使其可以顺利执行或被其他程序使用。它解决了跨模块的符号引用和地址变化等问题,并生成最终的输出文件。

    • 静态链接
      在这里插入图片描述

    • 装入时动态链接在这里插入图片描述

    • 运行时动态链接
      在这里插入图片描述

    我们总结一下这一章:
    在这里插入图片描述

    什么是内存管理?

    内存空间的分配与回收

    在这里插入图片描述

    内存空间的扩展(实现虚拟性)

    在这里插入图片描述

    地址转换

    在这里插入图片描述

    地址转换三种方式

    在这里插入图片描述

    内存保护

    在这里插入图片描述
    内存保护的两种方式

    在这里插入图片描述
    在这里插入图片描述

    最后我们总结一下这一章:
    在这里插入图片描述

    覆盖与交换技术

    在这里插入图片描述

    覆盖技术

    在这里插入图片描述
    在这里插入图片描述

    交换技术

    在这里插入图片描述

    复习一下进程调度
    在这里插入图片描述

    在这里插入图片描述

    最后我们总结一下这一章:
    在这里插入图片描述

    内存的分配与回收

    在这里插入图片描述

    单一连续分配

    在这里插入图片描述

    固定分区分配

    在这里插入图片描述

    分区说明表
    在这里插入图片描述

    动态分区分配(可变分区分配)

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    系统要用怎样的数据结构记录内存的使用情况呢?

    在这里插入图片描述
    当多个空闲分区都能满足要求时,应该选择哪个分区进行分配?

    在这里插入图片描述
    如何进行分区的分配?

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    如何进行分区的回收?

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    内部碎片与外部碎片

    在这里插入图片描述
    在这里插入图片描述

    最后总结一下本章内容:

    在这里插入图片描述

    动态分区分配算法

    在这里插入图片描述

    首次适应算法

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    最佳适应算法

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    最坏(大)适应算法

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    临近适应算法

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    四种算法归纳比较

    在这里插入图片描述

    分页存储

    在这里插入图片描述
    在这里插入图片描述

    基本分页存储管理的思想

    在这里插入图片描述

    分页存储管理的重要概念

    在这里插入图片描述

    如何实现地址的转换

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    如何计算页号和页偏移量

    在这里插入图片描述
    为什么页面大小一般设为2的整数次幂?

    在这里插入图片描述

    在这里插入图片描述

    分页存储的逻辑结构

    在这里插入图片描述

    如何知道页面在内存中的起始地址?

    在这里插入图片描述
    在这里插入图片描述

    最后我们总结一下这一章的内容:
    在这里插入图片描述

    分页存储管理的基本地址变换结构

    在这里插入图片描述

    页表寄存器

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    例题:
    在这里插入图片描述

    对页表项大小的进一步讨论

    在这里插入图片描述

    总结一下:
    在这里插入图片描述

    快表的地址变换结构

    我们前面说了分页存储管理的基本地址变换结构,这一章是对基本地址变换结构的改进版。

    在这里插入图片描述

    什么是快表

    在这里插入图片描述

    能否把整个页表都放在TLB中?
    在这里插入图片描述

    局部性原理引入快表机制

    在这里插入图片描述

    引入快表后,地址的变换过程

    一个例图了解基于快表的地址变换结构

    在这里插入图片描述
    引入快表后,地址变换的过程的文字描述:
    在这里插入图片描述
    在这里插入图片描述

    基本地址变换与快表地址变换的比较

    在这里插入图片描述

    二级页表

    为什么引入二级页表?

    因为单级页表存在一些问题,所以引入二级页表和多级页表,有两个问题:

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    二级页表的原理和地址结构

    • 对页表再次分组
      在这里插入图片描述

    • 二级页表的地址结构及对应关系
      在这里插入图片描述

    如何实现二级页表的地址变换?

    在这里插入图片描述
    上面的部分我们解决了问题一,接下来是问题二,这里简单叙述一下,后面的文章会继续深入剖析。

    在这里插入图片描述

    几个小细节

    在这里插入图片描述

    最后总结一下:
    在这里插入图片描述

    基本分段存储管理

    在这里插入图片描述

    什么是分段?

    在这里插入图片描述

    分段的逻辑地址结构

    在这里插入图片描述

    段表

    在这里插入图片描述

    地址变换

    在这里插入图片描述
    在这里插入图片描述

    分段、分页管理的对比

    在这里插入图片描述
    在这里插入图片描述

    分段实现信息共享共享

    在这里插入图片描述

    为什么分页不方便实现信息共享和保护?

    在这里插入图片描述

    分段比分页更容易实现信息共享的原因主要有:

    1. 分段的地址空间是逻辑地址空间,与物理地址空间分离。每个段都有一个段表,映射逻辑地址到物理地址。这个映射可以在不同的进程中共享,所以多个进程可以共享同一个段。
    2. 分段允许段重叠,不同进程可以共享某些段。而分页的页映射通常是唯一的,不允许重叠,所以难以直接在地址空间中共享页面。
    3. 分段的粒度较大,通常是一个函数、数据结构等,更适合作为共享单元。而分页的页大小较小,不太方便作为共享信息的基本单元。
    4. 分段可以实现共享只读段,多个进程只读访问同一段,而分页实现只读共享页较为困难。

    具体例子:

    • 共享程序代码段:多个进程可以共享只读的代码段,从而减少内存占用。
    • 共享库段:多个进程可以共享动态链接库的代码和数据段。
    • 共享数据段:多个进程共享只读数据段,如常量数据。
    • 堆栈段不共享:每个进程有自己的唯一堆栈段。

    相比而言,分页实现共享信息较为困难,通常需要更复杂的机制,如复制现有的共享页等,比较低效。所以,总体来说,分段更容易高效实现信息共享。

    最后总结一下:
    在这里插入图片描述

    段页式存储管理

    在这里插入图片描述

    分页、分段的优缺点分析

    在这里插入图片描述
    在这里插入图片描述

    分段+分页=段页式管理

    在这里插入图片描述

    段页式管理的逻辑地址结构

    在这里插入图片描述

    段页式存储的段表、页表

    在这里插入图片描述

    段页式管理的地址转换过程

    在这里插入图片描述

    最后总结一下:
    在这里插入图片描述

    虚拟内存

    在这里插入图片描述
    在这里插入图片描述

    传统存储管理的特征、缺点

    在这里插入图片描述

    局部性原理

    在这里插入图片描述

    虚拟内存的定义和特征

    在这里插入图片描述
    在这里插入图片描述

    如何实现虚拟内存技术

    在这里插入图片描述

    最后总结一下:
    在这里插入图片描述

    请求分页管理方式

    在这里插入图片描述

    页表机制—请求页表与基本页表的区别

    在这里插入图片描述

    缺页中断机构

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    地址变换机构

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    最后总结一下:
    在这里插入图片描述

    页面置换算法

    在这里插入图片描述

    最佳置换算法—OPT

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    先进先出置换算法—FIFO

    在这里插入图片描述
    在这里插入图片描述

    最近最久未使用置换算法—LRU

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    时钟置换算法—CLOCK

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    改造型时钟置换算法

    • 只需一轮
      在这里插入图片描述

    • 需要两轮
      在这里插入图片描述

    • 需要三轮:
      在这里插入图片描述
      在这里插入图片描述

    • 需要四轮
      在这里插入图片描述在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    总结:
    在这里插入图片描述

    页面分配策略

    在这里插入图片描述

    驻留集

    在这里插入图片描述

    驻留集(Resident Set)是操作系统管理内存的一个重要概念。它指的是一个进程当前占用的内存页面集合。

    当一个进程运行时,它需要从辅助存储器(如硬盘)将代码和数据读入内存。不可能将整个进程的所有代码和数据都读入内存,因为内存有限。所以,操作系统会根据一定的页面置换算法(如LRU),选择将一些页面驻留在内存中,这些驻留在内存中的页面集合就是驻留集。

    驻留集是描述一个进程运行时实际占用内存的页面集合,它的大小和内容随着进程的运行而动态变化,密切相关到操作系统的内存管理和进程调度。

    页面分配、置换策略

    在这里插入图片描述

    固定分配局部置换、可变分配局部置换、可变分配全局置换

    在这里插入图片描述
    在这里插入图片描述

    何时调入页面?

    在这里插入图片描述

    从何处调页?

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    抖动(颠簸)现象

    在这里插入图片描述

    工作集

    工作集(Working Set)是操作系统内存管理的一个重要概念,与驻留集相类似,但有一定区别。

    工作集指的是进程在最近一段时间内实际访问的页面集合。它表示进程近期的内存访问局部性,通过工作集的大小可以反映出进程最近一段时间的内存使用情况和访问模式。

    操作系统通过定期统计每个进程的工作集,来发现进程的内存访问模式的变化。当工作集大小发生较大变化时,说明进程的内存访问模式可能已发生改变,这时操作系统会相应地调整进程的驻留集,以适应新的工作集大小和访问模式。

    工作集与驻留集的主要区别在于:

    1. 工作集反映的是进程最近一段时间的内存访问情况,它是短期的和动态变化的。而驻留集表示进程当前占用的内存,它由工作集演变而来,相对而言是较长期和稳定的。
    2. 工作集的页面可能没有全部驻留在内存,而驻留集中的页面全部在内存中。工作集只是访问的页面集合,不代表这些页面实际驻留在内存。
    3. 操作系统不直接管理工作集的大小,它通过STATISTICS得到工作集信息,并据此调整驻留集。而驻留集的大小由操作系统的页面置换算法直接管理。
    4. 工作集用于发现进程内存访问模式的变化,指导驻留集的调整,而驻留集直接影响进程的运行效率。

    总之,工作集和驻留集都描述进程占用和访问的内存,但工作集更注重内存访问模式,用于发现进程内存模式的变化;而驻留集直接影响进程运行,由操作系统根据工作集信息加以管理。两者互为依存,共同服务于操作系统的内存管理。
    在这里插入图片描述

    总结:

    在这里插入图片描述

  • 相关阅读:
    从零开始学习 Java:简单易懂的入门指南之网络编程(三十七)
    一文读懂Web3 结算协议 Zebec Protocol 的商业模式与发展前景
    leetcode:2454. 下一个更大元素 IV【sortedDict初探 + 双单调栈学习】
    基于Java的毕业设计选题管理系统设计与实现(源码+lw+部署文档+讲解等)
    生成全世界唯一的uuid(golang实现)
    消防安全知识答题小程序v3.0已迭代完成
    mysql简单入门常见的语句使用
    新闻管理系统(SpringBoot+Vue)
    多任务并发执行,最终返回的例子
    C#:实现分枝绑定背包求解器算法(附完整源码)
  • 原文地址:https://blog.csdn.net/zyb18507175502/article/details/130643126
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号