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

Linux笔记---分页存储管理

1. 存储管理方式

操作系统如何管理有限的物理内存空间,在满足各个进程要求的前提下尽可能提高内存利用率呢?

1.1 连续分配存储管理方式

早期的操作系统普遍采用连续分配存储管理方式,主要包括如下3种:

  • 单一连续分配
    • 原理:内存分为系统区和用户区,用户进程独占用户区。
    • 优点:简单。
    • 缺点:仅支持单任务,内存利用率极低(内部碎片严重)。
  • 固定分区分配
    • 原理:内存划分为多个固定大小的分区,进程分配到适合的分区。
    • 优点:支持多任务。
    • 缺点:内部碎片和外部碎片均存在。
  • 动态分区分配
    • 原理:按需动态分配连续内存块,如首次适应、最佳适应算法。
    • 优点:减少内部碎片。
    • 缺点:外部碎片严重(需紧凑技术合并碎片)。

显然,这三种管理方式的思想非常的简单,并且存在显著的碎片问题。

在操作系统的存储管理中,碎片(Fragmentation) 是指内存空间被分割成许多小块,导致内存无法被有效利用的现象。碎片分为两种类型:内部碎片外部碎片,它们的成因和影响不同。

内部碎片(Internal Fragmentation):已分配给进程的内存块中未被使用的部分。

外部碎片(External Fragmentation):内存中未被分配的零散空闲区域,但总和足够大却无法满足进程需求

 1.2 Linux存储管理方式

现代的操作系统普遍采用的就是分页式存储管理 + 虚拟存储管理。

1.2.1 分页式存储管理

分页式存储管理将物理内存和逻辑地址空间划分为固定大小的“页”(Page,物理内存中的页称为“页框/帧”)。在Linux当中,每一页的大小为4KB,大小恰好为一个数据块。

所以,与文件系统类似地,操作系统对内存进行访存地基本单位也是4KB,即一个页面。

这样,操作系统就不再需要将完整地一块内存一次性分配给进程了,而是将分散的一个个页面分配给进程,大大地提高了内存地使用效率(进程所拥有的页面当中,只有最后一个页面当中可能存在碎片,最多也就4KB。并且只要空闲内存的总合达到进程要求即可分配,不需要找到一块连续的符合要求的大内存块)。

因为每一块页面的大小都是确定的,所以,我们只需要知道页面的编号即可计算出其地址:PageAddr = PageNum * 4KB

除了概念当中提到的页面划分,分页式存储管理的原理还包括以下四点:

  • 逻辑地址结构:逻辑地址分为两部分:页号(P)页内偏移(d)。当页面大小为2^nB时,逻辑地址的低n为就作为页内偏移(n位刚好寻址2^n个内存单元),剩余的高位作为页号(或者页面寻址)。当页面大小为4KB时,低12位就用作页内偏移。
  • 页表(Page Table):每个进程维护一个页表,记录逻辑页号到物理页框号的映射关系。全局页表用于内核区的映射,所有进程共享,而用户页表则由进程自己拥有。
  • 地址转换:物理地址 = 物理页框号 × 页面大小 + 页内偏移。
  • 硬件支持:需要内存管理单元(MMU)实现地址转换(x86CPU中CR3寄存器负责存放页表在物理内存中的地址,将实际物理页面地址与低位页内偏移由硬件完成),可能引入快表(TLB)加速查询(将部分常用的页表项放入特定的高速缓冲区,称为快表)。

下图中,系统为进程分配了两个页面,用户定义的变量a位于页面1,变量b位于页面5。通过查询页表,我们能够找到这两个页面在内存当中分别位于页面4和6。此时,在页面基地址的基础之上,加上页内偏移就可以找到这两个变量在物理内存空间中的地址。

 1.2.2 多级页表

现在的操作系统都支持非常大的逻辑地址空间(2^{32} ~ 2^{64})。对于一个32位的分页系统来说,一个进程的页表项数可达1M之多,没个页表项占用4B,则光是页表都可占用4MB的内存空间。

显然,页表太大了,以至于一个页面无法完全放下,此时我们就引入了页表的页表,即多级页表。

在32位系统下,二级页表的最大寻址范围刚好是4GB,Linux使用的正是二级页表:

1.2.3 虚拟存储管理

由于分页式存储管理的引入,进程在运行时不一定需要将自己的数据全部加载到内存,而是只将自己需要的几个页面加载到内存。

当进程发现自己需要的页面不在内存当中时(页表项存在,但是对应的物理页表号不存在),就会触发缺页中断,操作系统响应之后就会将进程需要的页面加载到内存当中并完善页表当中的映射(换入)。

假设此时所有的物理内存都被占用,就需要将其他进程暂时不用的页面换出

上述过程也称为对换

这一机制的引入,使得操作系统能在物理内存有限的情况下,支持更大的虚拟内存。

当然,实际实现起来肯定会比我们讲的复杂得多,我们只是简单引入一下这些概念。

1.3 其他存储管理方式

  • 分段式存储管理
    • 原理:按逻辑单元(代码段、数据段等)划分段,每段长度可变。
    • 地址结构:段号 + 段内偏移,通过段表映射到物理地址。
    • 优点:支持模块化编程,便于共享和保护。
    • 缺点:外部碎片问题,内存利用率低于分页。
  • 段页式存储管理
    • 原理:结合分段和分页,先分段,段内再分页。
    • 优点:兼具分段和分页的优势(逻辑清晰、无外部碎片)。
    • 缺点:管理复杂,需维护段表和页表,地址转换开销大。

 实际上,Linux在进程的管理上也有分段的概念,详见:Linux笔记---进程:进程地址空间-CSDN博客。

所以Linux本质来说采用的是分页式存储管理,但在进程地址空间的管理当中具有分段式存储管理的特点,可以说是段页式存储管理的变体。

2. 总语

本文只是对操作系统当中的存储管理方式做了一个简单的介绍,目的是为了让读者更好地理解Linux操作系统的存储管理方式。

如果要深入学习这些操作系统当中的存储管理方式,本文是远远不够的。

http://www.xdnf.cn/news/650809.html

相关文章:

  • 从OTA双雄「共舞」,透视旅游持续繁荣背后的结构性跃迁
  • BERT分类器和朴素贝叶斯分类器比较
  • 大语言模型 提示词的少样本案例的 演示选择与排序新突破
  • Baklib内容中台效能跃升实践
  • 什么是3D全景视角?3D全景有什么魅力?
  • 大语言模型(LLM)入门项目推荐
  • Java设计模式之模板方法模式:从基础到高级的全面解析(最详解)
  • Docker基础 -- Ubuntu 22.04 AArch64 交叉编译 Docker 镜像构建指南
  • Linux Docker 安装oracle19c数据库教程
  • ceph 剔除 osd
  • Serverless成本优化实战:从资源浪费到精准管控的架构演进
  • RabbitMQ 应用 - SpringBoot
  • OpenSSL 与 C++ 搭建一个支持 TLS 1.3 的服务器
  • 图论:floyed算法
  • Go语言开发的GMQT物联网MQTT消息服务器(mqtt Broker)支持海量MQTT连接和快速低延时消息传输-提供源码可二次开发定制需求
  • 支持向量机(SVM)例题
  • cursor/vscode连接低版本的系统(glibc<2.28)
  • 基于Python与Flask的新能源汽车可视化大屏系统技术解析
  • 哈希表day5
  • VB.NET与SQL连接问题解决方案
  • SpringMVC怎样设置JSP视图解析器才能让页面跳转更高效?
  • 《Drain日志解析算法》论文阅读笔记
  • 企微获取会话内容,RSA 解密函数
  • 从零开始学电机(一)认识电机
  • [Java恶补day7] 42. 接雨水
  • 聊天室H5实时群聊聊天室全开源系统(源码下载)
  • 篇章三 基础——不可变类
  • 工信部中文点选验证码识别
  • Engineering a direct k-way Hypergraph Partitioning Algorithm【2017 ALENEX】
  • 基于JWT+Redis的登录流程实现