存储器管理(2)

简介: 存储器管理

存储器管理(1)https://developer.aliyun.com/article/1530584

5.1 程序的装入与链接

  1. 编译
  2. 链接
  3. 装入
  • 由装入程序将装入模块装入内存

1.地址绑定与内存保护

需要完成逻辑地址到物理地址的变换

内存保护

在地址变换过程中我们需要保证os不被用户访问和其他进程不受干扰.

这需要确定一个进程的合法地址范围,通过基地值寄存器和界限寄存器来实现保护

基地址<=物理地址<(基地址+界限地址)

2.程序的装入🍤

  1. 绝对装入方式
  2. 可重定位方式
  3. 动态运行时装入方式
  • 在把装入模块装入内存后,并不会立即将装入模块的相对地址变换为绝对地址,而是推迟到执行时才进行

5.2 覆盖与交换

1.覆盖

思想:将程序分为多个段(多个模块).常用的段常驻在内存,不常用的段在需要时调入内存

把内存划分为一个固定区和若干个覆盖区,固定区存放用户程序经常活跃的部分,调入后就

不再调出(除非运行结束),其余部分按调用大尔力权w1B田前系依将L调入覆盖区,替换原有调入内存,用不到时调出内存。其他放在外存,在需要调用前,系统将其调入覆盖区,替换原有

的段。必须由程序员声明覆盖结构,操作系统完成自动覆盖。

2.交换

把处于等待状态的进程或者被CPU剥夺运行权限的进程从内存移出到外存,这一过程称为换出;把准备好竞争CPU的进程从外存移到内存,这一过程称为换入。

暂时换出外存等待的进程状态为挂起状态(挂起态)。

挂起态又可以进一步细分为就绪挂起、阻塞挂起两种状态。

5.3 连续分配存储管理方式

连续分配方式可分为三类:单一连续分配、固定分区分配、动态分区分配。

单一连续分配

内存分为系统区和用户区

特点:

内存中只能有一道用户程序,用户程序独占整个用户区空间。优点:实现简单;

无外部碎片;

可以采用覆盖技术扩充内存;

固定分区分配

分区大小的预分配可能会导致内存浪费或分配不足的问题。

  • 分区大小相同的方式
  • 分区大小不等的方式

优点:实现简单,无外部碎片。缺点:

  1. 当用户程序太大时,可能所有的分区都不能满足需求,此时不得不采用覆盖技术来解决,但又会降低性能;
  2. 会产生内部碎片,内存利用率低。

题1.分区分配内存管理方式的主要保护措施是().

A.界地址保护

B.程序代码保护

C.数据保护

D.栈保护

解析:分区分配存储管理方式的保护措施是设置界地址寄存器。每个进程都有自己独立的进程空间,,如果一个进程在运行时所产生的地址在其地址空间之外,则发生地址越界。当程序要访问某个内存单元时,由硬件检查是否允许,如果允许则执行,否则产生地址越界中新,

由OS进行相应处理。

动态分区分配

动态分区分配又称可变分区分配,是一种动态划分内存的分区方法。

这种分配方式不会预先划分内存分区,而是在进程装入内存时,根据进程的大小动态地建立分区。系统分区的大小和数目是可变的。

两种常用的数据结构:空闲分区表空闲分区链

首次适应(First Fit)算法。

空闲分区以地址递增的次序链接。分配内存时顺序查找,找到大小能满足要求的第一个空闲分区。

最佳适应(Best Fit)算法。

空闲分区按容量递增的方式形成分区链,找到第一个能满足要求的空闲分区。

缺点:会产生很多的外部碎片。

最坏适应(Worst Fit)算法。

又称最大适应(Largest Fit)算法,全内刀区以合里足减人链接,找到第一个能满足要求的空闲分区,即挑选出最大的分区。

缺点:不利于后续大进程使用,会造成后续大进程到达时无内存分区可用。

找到能够容纳该进程大小的最大空闲分区后这个分区没用完的部分怎么处理

当最坏适应算法找到能够容纳进程大小的最大空闲分区后,该分区可能会有一部分空闲空间未被使用。这个未使用的部分可以成为一个新的空闲分区,可以进一步被分配给其他进程。

在处理这个未使用的部分时,通常会更新该分区的大小和位置信息。如果未使用的部分足够大,可以将其标记为一个新的空闲分区,并将其添加到空闲分区列表中,以备后续的内存分配请求使用。

更新空闲分区的大小和位置信息时,需要确保分区之间的内存空间不会出现碎片化问题。这可能涉及到对相邻的空闲分区进行合并,以形成更大的连续空闲区域。通过合并相邻的空闲分区,可以减少碎片化,并提供更大的可用空间来满足较大的内存请求。

总结起来,当最坏适应算法找到最大空闲分区后,未使用的部分可以被标记为新的空闲分区,并添加到空闲分区列表中。在更新空闲分区信息时,可能需要对相邻的空闲分区进行合并,以减少碎片化并提供更大的连续空闲空间。这样可以更有效地利用内存资源。

邻近适应(Next Fit) 算法。

又称循环首次适应算法,由首次适应算法演变而成。不同之处是,

分配内存时从上次查找结束的位置开始继续查找。

(首次适应算法每次都从低地址查找所以会留下很多小的空闲分区)

这种算法可能会导致产生很多小的空闲分区的原因是,当一个进程释放了一块内存后,该算法会从低地址开始搜索空闲分区。如果内存中存在多个相邻的小空闲分区,而当前进程需要的内存大小与其中一个小空闲分区的大小相等或略大,那么该算法就会选择这个小空闲分区来满足请求。这样一来,如果有多个进程反复分配和释放内存,而它们的内存需求大小比较接近,就会导致产生很多小的空闲分区。这些小的空闲分区可能无法满足大内存请求,从而导致内存碎片化的问题。内存碎片化指的是内存空间被分割成许多不连续的小块,虽然总的剩余空间足够,但是无法满足大内存请求,从而浪费了一些可用的内存空间。为了解决这个问题,可以使用其他的内存分配算法,如最佳适应算法(Best Fit Algorithm)或最坏适应算法(Worst Fit Algorithm),它们可以更好地利用内存空间,减少碎片化问题的发生。

5.4 非连续分配存储管理方式

非连续分配管理方式根据分区的大小是否固定,分为分页存储管理方式、

分段存储管理方式和段页式存储管理方式。

1. 分页存储管理方式

算法思想:把内存分为一个个相等的小分区,再按照分区大小把进程拆分成一个个小部分,分页

存储管理不会产生外部碎片。

把进程的地址空间分为若干页,把内存空间分为若干块

页面

进程最后一页经常装不了一块,所以会形成不可用的碎片—页内碎片

页面大小应是2的幂

地址结构

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

解析: 4GB=232B, 4KB=2l2 B

因此4GB的内存总共会被分为232/212 = 20个内存块,因此内存块号的范围应该是0~20-1,因

此至少要20个二进制位才能表示这么多的内存块号,因此至少要3个字节才够(每个字节8个二进

制位,3个字节共24个二进制位)。

刚开始进程未执行的时候页表起始地址和页表放在PCB中,执行之后放在页表寄存器中

变换过程计算:

设页面大小为L,逻辑地址A到物理地址E的变换过程如下(逻辑地址、页号、每页

的长度都是十进制数) :

  1. 计算页号P(P= A/L)和页内偏移量W(W = A%L)。
  2. 比较页号P和页表长度M,若P> M,则产生越界中断,否则继续执行。
  3. 页表中页号P对应的页表项地址=页表始址F +页号P X页表项长度,取出该页表项内
    容b,即为物理块号。
    要注意区分页表长度和页表项长度。页表长度的值是指一共有多少页,页表项长度是指页
    地址占多大的存储空间。
  4. 计算E=b * L+ W,用得到的物理地址E去访问内存。

具有块表的页面变换结构

快表,又称联想奇存器(TLB),是一种访问速度比内存快很多的高速缓冲存储器,用来存

放当前访问的若干页表项,以加速地址变换的过程。快表命中,只需一次访存, 快表未命中,

需要两次访存。

2.分段存储管理方式

段表:每个段表项对应进程的一段,段表项记录该段在内存中的始址和长度。

地址变换结构

在系统中设置了段表寄存器,用于存放段表始址F段表长度M。从逻辑地址A到物

理地址E之间的地址变换过程如下:

3.段页式存储管理方式

相关文章
|
10月前
|
人工智能 自然语言处理 搜索推荐
AI 零成本搭建个人网站,小白 3 步搞定!通义灵码智能体+MCP 新玩法
通过AI技术,即使不编写代码也能高效开发项目。从生成诗朗诵网页到3D游戏创建,这些令人惊叹的操作如今触手可及。经过摸索,我利用AI成功上线了个人站点:https://koi0101-max.github.io/web。无需一行代码,借助强大的工具即可实现创意,让开发变得简单快捷!
3109 72
|
人工智能 算法 JavaScript
无界 SaaS AI 生态大模型:技术在中国,链接全世界
无界 SaaS AI 生态大模型涵盖前端用户界面、后端服务器逻辑、数据库设计、API 接口开发及区块链技术应用。本文提供一个简化框架,介绍技术栈选择、核心功能模块(用户管理、商城、数据确权、链接力、算力算法、AI 生态大模型、全球化支持)及后端示例代码,帮助将商业模式转化为代码。
|
存储 算法 开发工具
Git 暂存区机制详解
从[git init 执行后发生了什么](https://segmentfault.com/a/1190000044544615)我们知道,Git 经过初始化后,会形成三个主要区域:工作目录(Working Directory)、暂存区(Staging Area)和版本库(Repository
545 0
Git 暂存区机制详解
Java中的多线程编程:基础知识与实战技巧
【5月更文挑战第6天】多线程编程是Java中的一个重要特性,它允许我们在一个程序中同时执行多个任务。本文将介绍Java多线程的基础知识,包括线程的创建、启动、同步和通信,以及如何在Java中实现多线程编程。通过实例代码和解析,帮助读者深入理解Java多线程编程的概念和应用。
134 3
|
存储 算法 安全
JVM-内存划分-垃圾回收器-回收算法-双亲委派-三色标记
JVM-内存划分-垃圾回收器-回收算法-双亲委派-三色标记
|
Kubernetes 应用服务中间件 网络安全
CentOS7上二进制部署Kubernetes高可用集群(v1.18版本)
CentOS7上二进制部署Kubernetes高可用集群(v1.18版本)
843 0
|
算法 安全
|
Linux 应用服务中间件 nginx
docker 快速查询容器是否正常启动
docker 快速查询容器是否正常启动
2426 0