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

操作系统-内存管理

虚拟内存

操作系统会提供⼀种机制,将不同进程的虚拟地址和不同内存的物理地址映射起来。

两个概念:

  • 程序所使⽤的内存地址叫做虚拟内存地址(Virtual Memory Address)
  • 实际存在硬件⾥⾯的空间地址叫物理内存地址(Physical Memory Address)

管理虚拟地址与物理地址的两种方式:

  • 内存分段管理
  • 内存分页管理
     

内存分段

程序是由若⼲个逻辑分段组成的,如可由代码分段、数据分段、栈段、堆段组成。 不同的段是有不同的属性的,所以就⽤分段(Segmentation)的形式把这些段分离出来。

分段机制下的虚拟地址由两部分组成,段选择因子和段偏移量

  • 段选择因⼦就保存在段寄存器⾥⾯。段选择⼦⾥⾯最重要的是段号,⽤作段表的索引。 段表⾥⾯保存的是这个段的基地址、段的界限和特权等级等。
  • 虚拟地址中的段内偏移量应该位于 0 和段界限之间,如果段内偏移量是合法的,就将段基地址加上段内偏移量得到物理内存地址。
     

不足之处:

  • 第⼀个就是内存碎⽚的问题。
  • 第⼆个就是内存交换的效率低的问题。
     

内存碎片问题

假设有 1G 的物理内存,⽤户执⾏了多个程序,其中:

  • 游戏占⽤了 512MB 内存
  • 浏览器占⽤了 128MB 内存
  • ⾳乐占⽤了 256 MB 内存

这个时候,如果我们关闭了浏览器,则空闲内存还有 1024 - 512 - 256 = 256MB。
如果这个 256MB 不是连续的,被分成了两段 128 MB 内存,这就会导致没有空间再打开⼀个 200MB 的程序。

产生碎片的地方:

  • 外部内存碎⽚,也就是产⽣了多个不连续的⼩物理内存,导致新的程序⽆法被装载;
  • 内部内存碎⽚,程序所有的内存都被装载到了物理内存,但是这个程序有部分的内存可能并不是很常使⽤,这也会导致内存的浪费

解决:内存交换

可以把⾳乐程序占⽤的那 256MB 内存写到硬盘上,然后再从硬盘上读回来到内存⾥。不过再读回的时候,我们不能装载回原来的位置,⽽是紧紧跟着那已经被占⽤了的 512MB 内存后⾯。
 

内存交换效率低

因为硬盘的访问速度要⽐内存慢太多了,每⼀次内存交换,我们都需要把⼀⼤段连续的内存数据写到硬盘上。
所以, 如果内存交换的时候,交换的是⼀个占内存空间很⼤的程序,这样整个机器都会显得卡顿
 

内存分页

分⻚是把整个虚拟和物理内存空间切成⼀段段固定尺⼨的⼤⼩。这样⼀个连续并且尺⼨固定的内存空间,我们叫⻚(Page)。在 Linux 下,每⼀⻚的⼤⼩为 4KB 。
虚拟地址与物理地址之间通过⻚表来映射
 

⽽当进程访问的虚拟地址在⻚表中查不到时,系统会产⽣⼀个缺⻚异常,进⼊系统内核空间分配物理内存、更新进程⻚表,最后再返回⽤户空间,恢复进程的运⾏。
 

内存碎片、内存交换效率低解决

由于内存空间都是预先划分好的,也就不会像分段会产⽣间隙⾮常⼩的内存,这正是分段会产⽣内存碎⽚的原因。⽽采⽤了分⻚,那么释放的内存都是以⻚为单位释放的,也就不会产⽣⽆法给进程使⽤的⼩内存。
如果内存空间不够,操作系统会把其他正在运⾏的进程中的「最近没被使⽤」的内存⻚⾯给释放掉,也就是暂时写在硬盘上,称为换出(Swap Out)。⼀旦需要的时候,再加载进来,称为换⼊(Swap In)。所以,⼀次性写⼊磁盘的也只有少数的⼀个⻚或者⼏个⻚,不会花太多时间, 内存交换的效率就相对⽐较⾼
 

映射过程

简单分页缺陷

在 32 位的环境下,虚拟地址空间共有 4GB,假设⼀个⻚的⼤⼩是 4KB(2^12),那么就需要⼤约 100 万(2^20) 个⻚,每个「⻚表项」需要 4 个字节⼤⼩来存储,那么整个 4GB 空间的映射就需要有 4MB的内存来存储⻚表。
100 个进程的话,就需要 400MB 的内存来存储⻚表,这是⾮常⼤的内存了,更别说 64 位的环
境了。


 解决:多级页表

我们把这个 100 多万个「⻚表项」的单级⻚表再分⻚,将⻚表(⼀级⻚表)分为 1024 个⻚表(⼆级⻚表),每个表(⼆级⻚表)中包含 1024 个「⻚表项」,形成⼆级分⻚。如下图所示
 

你可能会问,分了⼆级表,映射 4GB 地址空间就需要 4KB(⼀级⻚表) + 4MB(⼆级⻚表)的内存,这样占⽤空间不是更⼤了吗?
当然如果 4GB 的虚拟地址全部都映射到了物理内存上的话,⼆级分⻚占⽤空间确实是更⼤了,但是,我们往往不会为⼀个进程分配那么多内存。
 

如果某个⼀级⻚表的⻚表项没有被⽤到,也就不需要创建这个⻚表项对应的⼆级⻚表了,即可以在需要时才创建⼆级⻚表。
 

对于 64 位的系统,两级分⻚肯定不够了,就变成了四级⽬录,分别是:

  • 全局⻚⽬录项 PGD(Page Global Directory);
  • 上层⻚⽬录项 PUD(Page Upper Directory);
  • 中间⻚⽬录项 PMD(Page Middle Directory);
  • ⻚表项 PTE(Page Table Entry);
     

问题:页表的级数较多,两个地址之间的转化较为缓慢

解决:TLB

就可以利⽤这⼀特性,把最常访问的⼏个⻚表项存储到访问速度更快的硬件,于是计算机科学家们,就在 CPU 芯⽚中,加⼊了⼀个专⻔存放程序最常访问的⻚表项的 Cache,这个 Cache 就是 TLB(Translation Lookaside Buffer) ,通常称为⻚表缓存、转址旁路缓存、快表等。

段页式管理

段⻚式内存管理实现的⽅式:

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

地址结构就由段号、段内⻚号和⻚内位移三部分组成。


段⻚式地址变换中要得到物理地址须经过三次内存访问:

  • 第⼀次访问段表,得到⻚表起始地址;
  • 第⼆次访问⻚表,得到物理⻚号;
  • 第三次将物理⻚号与⻚内位移组合,得到物理地址。
     

 

相关文章:

操作系统-内存管理

虚拟内存 操作系统会提供⼀种机制,将不同进程的虚拟地址和不同内存的物理地址映射起来。 两个概念: 程序所使⽤的内存地址叫做虚拟内存地址(Virtual Memory Address)实际存在硬件⾥⾯的空间地址叫物理内存地址(Physi…...

C++中的解释器模式

目录 解释器模式(Interpreter Pattern) 实际应用 算术表达式解释器 布尔表达式解释器 总结 解释器模式(Interpreter Pattern) 解释器模式是一种行为设计模式,它定义了一种语言的文法表示,并使用解释器…...

用 C 语言实现求补码的运算

缘起 前两天程序中需要求一堆参数的补码,一时犯懒,想从CSDN上搜一个勉强能用的代码借鉴一下,结果几乎没有搜到一个靠谱的!这种求补码的操作,用脚趾头想想也应该知道要用C或者C的位运算来实现呀。结果搜到的一些实现方…...

python下载文件

import urllib.request url "http://****/storage/x4MigEhU6BGAuTqjrRfIBky0S2aMmkyGl4UzTqUb.png"#下载地址 path "ddad.png"#保存路径,保存项目路径 urllib.request.urlretrieve(url, path)...

JMU 数科 数据库与数据仓库期末总结(1)

本章根据老师给出的知识点作进一步相对生动一点的解释。 不保证完全正确。 先给出总的知识点,再给出生动解释。 知识点 数据模型通常由三部分组成:数据结构、数据操作和完整性约束。关系模式中主码的取值必须唯一且非空,这是实体完整性的…...

前端问题整理

Vue vue mvvm(Model-View-ViewModel)架构模式原理 Model 是数据层,即 vue 实例中的数据View 是视图层, 即 domViewModel,即连接Model和Vue的中间层,Vue实例就是ViewModelViewModel 负责将 Model 的变化反映…...

【实践功能记录6】表格列悬浮展示tooltip信息

需求描述&#xff1a; 鼠标悬浮在表格的IP字段上时&#xff0c;使用tooltip展示IP信息&#xff0c;如图&#xff1a; 1.封装根据IP展示信息的组件 请求接口获取IP信息&#xff0c;注意请求接口时防抖 <!-- 根据IP展示资产信息 --> <template><div><el-…...

AI论文速读 | 2024[SIGIR]基于大语言模型的下一个兴趣点推荐

论文标题&#xff1a;Large Language Models for Next Point-of-Interest Recommendation 作者&#xff1a;Peibo Li ; Maarten de Rijke ; Hao Xue &#xff08;薛昊&#xff09;; Shuang Ao ; Yang Song ; Flora D. Salim 机构&#xff1a;新南威尔士大学(UNSW)&#xff0c…...

Rust 实战丨通过实现 json! 掌握声明宏

在 Rust 编程语言中&#xff0c;宏是一种强大的工具&#xff0c;可以用于在编译时生成代码。json! 是一个在 Rust 中广泛使用的宏&#xff0c;它允许我们在 Rust 代码中方便地创建 JSON 数据。 声明宏&#xff08;declarative macros&#xff09;是 Rust 中的一种宏&#xff0…...

vue+elementUI实现在表格中添加输入框并校验的功能

背景&#xff1a; vue2elmui 需求&#xff1a; 需要在一个table中添加若干个输入框&#xff0c;并且在提交时需要添加校验 思路&#xff1a; 当需要校验的时候可以考虑添加form表单来触发校验&#xff0c;因此需要在table外面套一层form表单&#xff0c;表单的属性就是ref…...

为国产加油:“缺芯少屏”暂缓,另一领域,也要加把劲

说起咱中国之前的“缺芯少屏”&#xff0c;真的是让人挺闹心的。 不过呢&#xff0c;为了改变这个状况&#xff0c;咱们的工程师们可是费了不少劲儿&#xff0c;辛辛苦苦努力了数十年。现在好了&#xff0c;咱们也迎来了柔性屏的时代。 柔性屏 说起来&#xff0c;在触摸屏或者…...

【Qnx】Qnx coredump解析

Qnx coredump解析 coredump文件 Qnx运行的程序崩溃时&#xff0c;会生成coredump文件。 默认情况下这些文件默认会保存在/var/log/*.core 文件中。 解析coredump文件&#xff0c;可以帮忙加快分析程序崩溃的原因&#xff0c;比如了解崩溃的堆栈。 通常可以使用gdb和coreinfo…...

超级签名源码/超级签/ios分发/签名端本地linux服务器完成签名

该系统完全在linux下运行&#xff0c;不存在使用第三方收费工具&#xff0c;市面上很多系统都是使用的是第三方收费系统&#xff0c;例如&#xff1a;某心签名工具&#xff0c;某测侠等&#xff0c;不开源而且需要每年交费&#xff0c;这种系统只是在这些工具的基础上套了一层壳…...

RocketMQ在Centos7系统上单机部署

最近因为一些信创问题&#xff0c;要将RabbitMQ替换为RocketMQ&#xff0c;因此在此分享一些RocketMQ在Centos7系统上单机部署相关过程。 优缺点 RocketMQ的优点&#xff1a; 性能优越&#xff1a;RocketMQ在处理大量消息时&#xff0c;性能优于RabbitMQ。当面临每秒数万到数…...

Vue37-非单文件组件

一、组件的两种编写形式&#xff1a; 非单文件组件&#xff1b;单文件组件。 二、创建一个组件 2-1、组件中的el 组件中不写el&#xff0c;不说为谁服务。 2-2、组件中的data 因为对象形式&#xff0c;多处复用的话&#xff0c;有引用关系&#xff0c;改一处&#xff0c;另一…...

CSS实现经典打字小游戏《生死时速》

&#x1f33b; 前言 CSS 中有这样一个模块&#xff1a;Motion Path 运动模块&#xff0c;它可以使元素按照自定义的路径进行移动。本文将为你讲解这个模块属性的使用&#xff0c;并且利用它实现我小时候电脑课经常玩的一个打字游戏&#xff1a;金山打字的《生死时速》。 &…...

推箱子-小游戏

学习目标&#xff1a; 巩固Java基础&#xff0c;数据类型、二维数组、条件语句等&#xff1b; 效果展示&#xff1a;...

AI数字人的开源解决方案

目前&#xff0c;国内外已经涌现出一些优秀的数字人开源解决方案&#xff0c;这些解决方案为开发者提供了构建数字人应用的工具和基础设施。以下是一些比较知名的数字人开源解决方案。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1…...

java写一个验证码

生成验证码 内容&#xff1a;可以是小写字母&#xff0c;也可以是大写字母&#xff0c;还可以是数字 规则 长度为5 内容中是四位字母&#xff0c;1位数字。 其中数字只有1位&#xff0c;但是可以出现在任意的位置。 package User;import java.util.ArrayList; import jav…...

【星海随笔】ELK优化

ELS 再遇到大的日志文件的时候不会自动进行清理的,我们可以通过 logrotate 转储工具进行操作。 该命令是基于 Cron 实现,由系统执行,当然也可以手动进行执行例如 logrotate -f configfile# more /etc/logrotate.confweekly // 默认每一周执行一次rotate轮转工作 r…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...