当前位置: 首页 > article >正文

【系统架构设计师】操作系统 ③ ( 存储管理 | 页式存储弊端 - 段式存储引入 | 段式存储 | 段表 | 段表结构 | 逻辑地址 的 合法段地址判断 )

文章目录

  • 一、页式存储弊端 - 段式存储引入
    • 1、页式存储弊端 - 内存碎片
    • 2、页式存储弊端 - 逻辑结构不匹配
    • 3、段式存储引入
  • 二、段式存储 简介
    • 1、段式存储
    • 2、段表
    • 3、段表 结构
    • 4、段内地址 / 段内偏移
    • 5、段式存储 优缺点
    • 6、段式存储 与 页式存储 对比
  • 三、逻辑地址 的 合法段地址
    • 1、合法 段地址 判断
    • 2、合法 段地址 判断 - 案例





一、页式存储弊端 - 段式存储引入




1、页式存储弊端 - 内存碎片


页式存储 将内存划分为 固定大小的页 , 如果 进程所需内存大小 不是 页大小 的整数倍 ,

进程的最后一个 内存页 势必会存在 未使用的内存空间 , 这就 100% 造成了一个内存碎片 ;


页式存储 导致了 内存 的利用率降低 , 尤其在频繁分配小内存时该弊端 对系统性能的影响 会进一步放大 ;


如 : 内存页 大小 为 4KB , 进程需要 5KB 内存时 , 需分配 2 个内存页 ;

  • 第一个内存页 的 4KB 内存空间 完全被使用了 ;
  • 第二个内存页 的 4KB 内存空间 只使用 1KB , 浪费了 剩余的 3KB 内存空间 , 这就造成了 内存碎片 ;

2、页式存储弊端 - 逻辑结构不匹配


页式存储 按大小 考虑 内存划分 , 没有考虑 代码运行逻辑 ,

可能导致 逻辑结构不匹配 , 程序的 逻辑模块 可能被分散在不同物理页中 , 导致缓存局部性差 , 影响性能 ,


如 : 实际调用某个程序时 , 程序文件并不是正好切割成 n 块 ,

有可能将 程序的重要代码 切割到两个内存页中 ,

一个循环体 的 代码 恰好 被切割到两个不同的 内存页 中 ,

最坏情况下 每次循环 可能 都需要 将 磁盘中的数据 加载到 物理内存 中 ,

循环持续几百万次回导致系统开销很大 , 降低系统性能 ;


3、段式存储引入


为了解决 页式存储 的 逻辑结构不匹配 的 弊端 , 段式存储 将内存 按逻辑段 ( 代码段、数据段、堆栈段 ) 划分 , 每个 逻辑段 长度可变 , 独立分配内存 , 与程序的实际结构对应 ;

段式存储 通过 段表 进行内存管理 , 通过 段表 记录每个段的 基址 ( 起始地址 ) 和 界限 ( 长度 ) , 实现动态映射 ;

段式存储 的 内存段长度 由实际需求决定 , 避免 页式存储 的 固定内存页大小 导致的浪费 ;





二、段式存储 简介




1、段式存储


段式存储 ( Segmentation ) 是一种 内存管理技术 , 它 将程序的 内存空间 按 自然逻辑段(代码段、数据段、堆栈段等)划分 , 每个 内存段 具有独立的 地址空间 和 长度 ;

段式存储的设计目标是更好地反映 程序的 逻辑结构 , 提供更灵活的内存管理和更高的安全性 ;

在这里插入图片描述


2、段表


段式存储 主要靠 段表 进行 内存管理 ;

<font color=bluered段表 ( Segment Table ) 是段式存储管理中的核心数据结构,用于记录每个逻辑段的基址(起始地址)和界限(长度)等信息。

通过段表,操作系统可以将程序的逻辑地址转换为物理地址,并实现内存的权限控制和保护。


段表 的 三大作用 :

  • 地址转换 : 将逻辑地址(段号 + 段内偏移量)转换为物理地址 , 逻辑地址 中的 段号 用于查找 段表 , 获取 段 的 基址 和 界限 ;
  • 内存保护 : 段表中可以记录每个段的访问权限(如只读、可写、可执行), 在地址转换时 , 操作系统会检查访问权限 , 防止非法访问 ;
  • 段的管理 : 段表记录了每个段的状态信息(如是否已加载到内存) , 便于操作系统管理内存 ;

3、段表 结构


段表 结构 :

  • 段基址(Base Address): 段内存 在 物理内存 中的 起始地址 ; 用于将 逻辑地址 中的 段内偏移量 转换为 物理地址 ;
    • 案例 : 段基址为 0x1000 , 段内偏移量为 0x200 , 则物理地址为 0x1200 ;
  • 段界限(Limit): 段的长度(单位 : 字节) ; 用于检查段内偏移量是否合法 , 若偏移量超出段界限 , 则触发段错误(Segmentation Fault) ;
  • 访问权限(Access Rights) : 段内存 的访问权限 , 用于实现内存保护 , 防止非法访问 ; 访问权限有以下三种 :
    • 只读(Read-Only): 段内容只能读取,不能修改。
    • 可写(Writable): 段内容可以修改。
    • 可执行(Executable): 段内容可以作为代码执行。
  • 存在位(Present Bit): 表示 段内存 中的数据 是否已经从 磁盘 加载到 内存中 ; 该字段用于处理段未加载的情况,触发缺段中断(Segment Fault)。
    • 1: 表示段已加载到内存。
    • 0: 表示段未加载到内存(可能被换出到外存)。
  • 修改位(Dirty Bit): 表示段是否被修改过。用于页面置换算法,决定是否需要将段写回外存 , 最近 修改过的 段 不应该被置换到 外存 中 ;
    • 1: 段已被修改。
    • 0: 段未被修改。
      共享位(Shared Bit): 表示段是否可被多个进程共享。用于实现内存共享,减少内存占用。
    • 1: 段可共享。
    • 0: 段不可共享。
  • 保护位(Protection Bit): 表示段的保护级别 ; 用于实现内存保护,防止用户程序访问内核数据。保护级别有两个级别分别是 :
    • 用户级(User Level): 普通用户程序可访问。
    • 内核级(Kernel Level): 仅操作系统内核可访问。
  • 扩展位(Extended Bits): 用于存储额外的信息,如段类型、段描述符类型等。提供更灵活的功能支持。
字段含义
段基址段在物理内存中的起始地址。
段界限段的长度(以字节为单位),用于检查段内偏移量是否合法。
访问权限段的访问权限(如只读、可写、可执行)。
存在位表示段是否已加载到内存中(1:已加载;0:未加载)。
修改位表示段是否被修改过(用于页面置换算法)。
共享位表示段是否可被多个进程共享。
保护位表示段的保护级别(如用户级、内核级)。
扩展位用于存储额外的信息(如段类型、段描述符类型等)。

4、段内地址 / 段内偏移


逻辑地址段号 和 段内偏移 组成 , 一般写为 ( 段号 , 段内偏移 ) , 如 : ( 0 , 88 ) 表示 段号 为 0 段内偏移为 88 字节 ;

段内地址 , 又称为 段内偏移 , 加上段的 起始地址 / 基址 ( 查询段表所得 ) 就是 对应的 物理地址 ;

在 程序的作业空间 中 , 每个 内存段 都有自己的 逻辑起始地址 , 段 起始地址 + 段内地址 就是 逻辑地址 ;


5、段式存储 优缺点


段式存储 优点 :

  • 减少内部碎片: 段长度由实际需求决定,避免 固定页大小导致的 内部碎片 浪费。
  • 逻辑结构匹配: 支持按段设置权限(如代码段只读、数据段可写),提升安全性。提高缓存和内存访问的局部性。
  • 内存灵活共享: 共享时可直接 共享整个段(如共享代码库)。

段式存储 缺点 :

  • 外部碎片(External Fragmentation): 由于段长度可变,频繁分配/释放会导致内存中出现大量不连续的小块空闲区域。需通过内存紧凑(Compaction)整理碎片,但开销较大。
  • 内存分配复杂度: 动态管理可变长度段需要 更复杂的算法(如首次适应、最佳适应)。

6、段式存储 与 页式存储 对比


段式存储 与 页式存储 对比 :

  • 页式存储: 把进程地址空间分成固定大小的页,与物理内存的页框映射,避免外部碎片,但可能有内部碎片。
  • 段式存储: 按逻辑划分进程地址空间,每段大小不同,适应性强,但可能有外部碎片。

对比项页式存储 (Paging)段式存储 (Segmentation)
基本单位页 (Page)段 (Segment)
地址结构页号 + 页内偏移量段号 + 段内偏移量
分配方式物理内存划分为固定大小的页物理内存划分为不同大小的段
地址连续性进程的逻辑地址空间不连续逻辑地址空间是连续的
内存管理采用页表(Page Table)映射采用段表(Segment Table)映射
外部碎片无外部碎片,但有内部碎片可能产生外部碎片
内部碎片可能有内部碎片(页不足时)无内部碎片
存储灵活性固定大小,适合动态分配变长,适合按需求分配
适用场景操作系统内存管理、虚拟内存代码、数据、栈分段存储




三、逻辑地址 的 合法段地址




1、合法 段地址 判断


软考 中 针对 段式存储 知识点 考察的是 逻辑地址 的 合法段地址 判断 ;

逻辑地址 由 " 段号 + 段内偏移 " 组成 , 一般使用 ( 段号 , 段内偏移 ) 表示 ,

如 : ( 0 , 99 ) 表示 段号 0 段内偏移 99 字节 ;


合法 段地址 的 段内偏移 在 段界限 ( Limit , 段的长度 ) 之内 ;

非法 段地址 的 段内偏移 超出了 段界限 ;


以下面的段表为例 :

应用程序 作业空间 的 段号为 0 的 段 , 对应 逻辑地址 , 该段 的 段界限 ( 段长 ) 为 30KB ,

逻辑地址 ( 0 , 25 ) , 段号 0 , 段内偏移 25KB , 小于 段界限 30KB , 该逻辑地址 就是 " 合法 " 的 逻辑地址 ;

逻辑地址 ( 0 , 35 ) , 段号 0 , 段内偏移 35KB , 大于 段界限 30KB , 该逻辑地址 就是 " 非法 " 的 逻辑地址 ;

在这里插入图片描述


2、合法 段地址 判断 - 案例


下图 是 某进程 的 段式内存管理 的 段表 :

在这里插入图片描述

逻辑地址 使用 ( 段号 , 段内偏移 ) 表示 ;


段号 0 的逻辑地址 段内偏移 只能是 0 ~ 799 , 段内偏移 大于等于 800 就是非法地址 ;

段号 1 的逻辑地址 段内偏移 只能是 0 ~ 49 , 段内偏移 大于等于 50 就是非法地址 ;

段号 2 的逻辑地址 段内偏移 只能是 0 ~ 199 , 段内偏移 大于等于 200 就是非法地址 ;

段号 3 的逻辑地址 段内偏移 只能是 0 ~ 579 , 段内偏移 大于等于 580 就是非法地址 ;

段号 4 的逻辑地址 段内偏移 只能是 0 ~ 99 , 段内偏移 大于等于 100 就是非法地址 ;


逻辑地址 ( 0 , 999 ) 是 非法的 逻辑地址 , 不能转换为对应的 物理地址 ,

因为 段号 0 的 段界限 / 段长 为 800 字节 , 段内偏移 999 超出了 段界限 ;

这就导致 逻辑地址 转换为 物理地址 时 , 会出现 地址越界 ;


http://www.kler.cn/a/541190.html

相关文章:

  • 【学习笔记】计算机网络(三)
  • Linux 创建进程 fork()、vfork() 与进程管理
  • DeepSeek之Api的使用(将DeepSeek的api集成到程序中)
  • 使用 Postman 进行 API 测试:从入门到精通
  • 利用UNIAPP实现短视频上下滑动播放功能
  • windows蓝牙驱动开发-蓝牙 LE 邻近感应配置文件
  • 打破静态网页:CSS 动画与过渡技术全解析
  • Aquatronica控制系统tcp存在信息泄露漏洞
  • 推荐系统Day1笔记
  • 新站如何快速被搜索引擎收录?
  • 【大模型技术】accelerate和deepspeed
  • NineData云原生智能数据管理平台新功能发布|2025年1月版
  • docker 安装 --在线方式
  • linux xfs (dm-0) 修复
  • 论文笔记-COLING2025-LLMTreeRec
  • 探索.NET Core的神秘侦探:CallerMemberName、FilePath、LineNumber
  • 51单片机蜂鸣器铃声代码
  • OpenEuler学习笔记(二十三):在OpenEuler上部署开源MES系统
  • 如何处理 React 中的错误边界?
  • 【Linux】之【bug】“sudo wpa_cli -i wlan0 scan“ 返回 FAIL-BUSY 解决
  • CSS(学习自用-day1)
  • [uniapp] 实现扫码功能,含APP、h5、小程序
  • web前端录制canvas视频和video的声音,并合并成一个文件进行下载
  • 无法在Django 1.6中导入自定义应用
  • 如何用Excel制作一个日历表/万年历
  • Linux——网络(https)