内存管理(mmu)/内存分配原理/多级页表

1.为什么要做内存管理?

随着进程对内存需求的扩大,和同时调度的进程增加,内存是比较瓶颈的资源,如何更好的高效的利于存储资源是一个重要问题。

这个内存管理的需求也是慢慢发展而来,早期总线上的master是直接使用物理地址,再到发展出对CPU进行内存管理的MMU,到现在给SOC内部的各个具有DMA功能的模块进行内存管理的IOMMU或者叫做SMMU

在没有内存管理的时代,物理空间只能连续的使用,一个进程要用多少存储,在进程开始就确定好了,但是进程在运行过程中由于程序局部性的原理,在一段时间内可能只使用了分配好的内存的一部分,其余大部分时间都是空闲的;另外一个问题就是在分配内存过程中会出现一些小的且不连续的内存空间,这些空间(内存碎片)无法满足任何进程的使用,造成了一定的空间浪费。

所以内存管理解决的就是就是两个问题:

  • 让进程在运行过程中动态分配存储空间,即根据需求在运行过程中不断的分配空间【这同时促进了多级页表的产生】,而不需要一次分配很大的空间,这样可以提高进程并行调度能力
  • 降低空间碎片的产生

内存管理采用虚拟地址到物理地址的映射,这种用虚拟空间来隔离进程的做法又促进了虚拟化/虚拟机【VM】的发展,本文先不讨论VM。

1.1 内存碎片

内存碎片是由内存的申请和释放产生的,通常分为内部碎片和外部碎片。

  1. 内部碎片是由于采用固定大小的内存分区,即以固定的大小块为单位来分配,采用这种方法,进程所分配的内存可能会比所需要的大,这多余的部分便是内部碎片。
  2. 外部碎片是由于未分配的连续内存区域太小,以至于不能满足任意进程所需要的内存分配请求,这些小片段且不连续的内存空间被称为外部碎片。

2.内存管理算法

linux每一个用户进程都对应有自己的页表,我们不禁要问这些页表或者说物理空间是如何分配的?为什么每个进程对应一个页表?

通俗的来讲,每一个用户进程看到的都是一样大小的虚拟空间,所以它们并不知道实际可用的物理地址有哪些。【物理地址空间的管理和分配是一个独立于这些用户进程的,实际是OS操作系统管理的】当运行一个新的进程时,OS根据当前可用的PA【OS知道哪些PA正在被使用】,建立VA到PA的映射,也就是产生一个新的对应该进程的页表【每一个进程运行时当前可用PA都是不一样的,所以每个进程都要自己的页表】。

2.1内存管理的伙伴系统算法

linux使用的时伙伴系统来管理和分配内存

  • Linux内核使用二进制伙伴算法来管理和分配物理内存页面, 该算法由Knowlton设计, 后来Knuth又进行了更深刻的描述.
  • 伙伴系统是一个结合了2幂次个分配器和空闲缓冲区合并计技术的内存分配方案, 其基本思想很简单. 内存被分成含有很多页面的大块, 每一块都是2^n个页面大小. 如果找不到想要的块, 一个大块会被分成两部分, 这两部分彼此就成为伙伴. 其中一半被用来分配, 而另一半则空闲. 这些块在以后分配的过程中会继续被二分直至产生一个所需大小的块. 当一个块被最终释放时, 其伙伴将被检测出来, 如果伙伴也空闲则合并两者.

具体的算法请参考本人的转载文章:

内存管理之伙伴系统分析-CSDN博客

3.多级页表及节省内存

页表:是存储PTE的一个内存分页,而PTE是描述VA与PA映射关系的entry。

多级页表结构分为PGD/PUD/PMD/PTE这几个层级,P代表page,G代表global,D代表目录(Director),U代表上级,M代表中间,T代表Table,E代表Entry,所以:

PGD:page global director

PUD:page upper director

PMD:page middle director

PTE:page table entry

PTE是页表项。他们之间的关系是层级结构,通过PGD访问到最低端的PTE,访问方式是上一层地址+偏移量(offset)。PTE+页内偏移量可以访问到具体的物理地址。

为什么要建立多级页表的结构呢?

先给出结论【经过确认的结论】就是多级页表是为了节省页表的存储空间。

举个例子,4GB的DDR空间,4KB的页大小,一个PTM 4B,总共需要4GB/4K=1M个PTE,如果每个进程都要产生并存储一个1Mx4B的PTE,就会占用不少内存空间。

只要进程需要寻址4GB内存空间的能力,无论建立多少级的页表,最终都需要1Mx4B的PTE,在加上多出来的几级页表存储空间只会更多,那么为什么会说多级页表可以节省内存空间呢?

在这里先做一个统一,最底层的PTE这一级我们叫做第一级,PMD,PUD,PGD分别是第二/三/四级【这里PMD/PUD只是一个相对的层级,可能代表有多个中间层和上层,也可能没有,这里假设每一个就代表一层】,这样最底层为底层的话,无论增加多少层它的叫法不变。

写到这里有一个问题:页表既然是存在内存中的,那么有没有为页表空间建立页表?

其实多级页表可以理解为对上级页表对下级页表建立的页表,比如只有两级页表,配置了第二级页表的基地址,我们可以用虚拟地址的高位来映射第一级页表的物理地址。这样就可以理解高层页表是为了底层页表能够不连续的存储

多级页表的好处是可以将PTE分散存储,而不是用连续的物理地址存储。即使只有一级的PTE页表,也可以根据程序运行的局部特性只在特定时刻生成一部分PTE页表,但关键不在于只生成一部分的PTE,而是只有一级页表的话需要连续物理地址空间,即使只生成一部分的PTE,这1Mx4B的地址空间也不能给别人用。【这一原因也是很多文章没有说清楚的地方

另外多级页表还有一个优势,就是可以将那些不常用的低级页表swap out到硬盘中,当进程再次访问到该页表映射的物理内存是,内核将页表从硬盘中swap in到内存中。当然最顶层的PGD页表是必须常驻内存的。

既然多级页表也是存储在DDR的页上的数据,那么和其他数据一样就可以经过cache来高速缓存,其对应的高速缓存cache就是TLB(translation lookaside buffer,转换后备缓冲区,又常被称为快表)。这里不在详细介绍。

总结起来多级页表能够节省内存空间的原因如下:

  • 将页表变为非连续存储,同时可以只生成当前需要的一段页表
  • 可以将不常用页表swap到硬盘

参考资料:

操作系统中的多级页表到底是为了解决什么问题? - 知乎

该问题的答主中bin的技术小屋的回答

4.程序的局部性原理

多次提到程序的局部性原理,如何来描述呢?

局部性原理表现为:时间局部性和空间局部性。时间局部性是指如果程序中的某条指令一旦执行,则不久之后该指令可能再次被执行;如果某块数据被访问,则不久之后该数据可能再次被访问;空间局部性是指一旦程序访问了某个存储单元,则不久之后,其附近的存储单元也将被访问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/352554.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【鸿蒙】大模型对话应用(一):大模型接口对接与调试

Demo介绍 本demo对接阿里云和百度的大模型API,实现一个简单的对话应用。 DecEco Studio版本:DevEco Studio 3.1.1 Release HarmonyOS API版本:API9 关键点:ArkTS、ArkUI、UIAbility、网络http请求、列表布局 官方接口文档 此…

玩转未来:Sui游戏峰会将于3月19日亮相GDC

Sui将在今年三月份的旧金山游戏开发者大会(Game Developer Conference, GDC)上推出其首个重大游戏活动,展示其为独立游戏到3A游戏提供动力,并为游戏开发人员开启吸引新玩家参与的能力。“Play Beyond:Sui游戏峰会”&am…

线程在操作系统以及java中的几种状态(源码分析)

操作系统中一般将线程划分为五种状态:新建、可运行(就绪)、运行、阻塞、终止 新建(New):当一个线程被创建时,它处于新建状态。此时,线程对象已经创建,但还没有分配到CPU资…

element plus使用问题

文章目录 element plusvue.config.js注意1、有时候会报错 not a function2、使用 ElMessage 报错3、 element plus 版本过高4、警告Feature flag VUE_PROD_HYDRATION_MISMATCH_DETAILS is not explicitly defined.5、报错 ResizeObserver loop completed with undelivered noti…

网络基础---初识网络

前言 作者:小蜗牛向前冲 名言:我可以接受失败,但我不能接受放弃 如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、局域网…

读取一个batch的图像并且显示出来

1读取一个batch用于训练 我们在训练模型的时候,除了观察图像的标签和尺寸,最好能读取一个batch的图像显示出来,观察原始图像和grountruth是否对应,如果正确才能正式开始后续的训练。 下面以一个皮肤病分割的数据集加以演示。 2…

保障接口安全的11个方法

一、参数校验 校验参数是否为空,有些接口中可能会包含多个参数,有些参数允许为空,有些参数不允许为空,需要对这些参数做校验,防止接口底层出现异常。校验参数类型,比如:age 是 int 类型的&…

对鸢尾花进行分类预测-----pycharm

项目说明 #项目: 对鸢尾花进行分类预测 #实例数量150个(3类各50个) #属性数量:4(数值型,数值型,帮助预测的属性和类) #特征:花萼长度,花萼宽度,花瓣长度,花瓣宽度 单位&#xff1…

HarmonyOS 鸿蒙组件启动规则(Stage模型)

组件启动规则(Stage模型) 启动组件是指一切启动或连接应用组件的行为: 启动UIAbility、ServiceExtensionAbility、DataShareExtensionAbility,如使用startAbility()、startServiceExtensionAbility()、startAbilityByCall()等相关…

FOC系列(五)----STM32F405RGT6控制板焊接与初步编写代码

声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。    首先祝大家新年快乐,因为我也快放假了,驱动板只能是开学之后再去测试了,本篇博客应该是本专栏年前的最后一篇了 一…

【计网·湖科大·思科】实验三 总线型以太网的特性、集线器和交换机的区别、交换机的自学习算法

🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要&…

字符串相关的函数和内存块相关函数

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - :来于“云”的“羽球人”。…

[学习笔记] ONNX 基础知识

1. ONNX 简介 1.1 什么是 ONNX 开放神经网络交换 ONNX(Open Neural Network Exchange)是一套表示深度神经网络模型的开放格式,由微软和 Facebook 于 2017 推出,然后迅速得到了各大厂商和框架的支持。通过短短几年的发展&#xf…

【JavaEE进阶】 #{}和${}

文章目录 🍃前言🌳#{}和${}使⽤🚩Interger类型的参数(基础数据类型)🎈使用#{}🎈使用${} 🚩String类型的参数使用🎈#{}使用🎈${} 🎍#{}和${}区别&a…

林浩然与极限的“无穷”约会

林浩然与极限的“无穷”约会 Lin Haoran’s Encounter with the Mathematical “Infinity” 在数学王国里,有一位名叫林浩然的大侠,他的江湖就是高等数学的殿堂。而他要挑战的终极Boss,便是那个既神秘又顽皮的“极限”。 In the kingdom of …

《golang设计模式》第三部分·行为型模式-10-模板方法(Template Method)

文章目录 1. 概述1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 模板方法(Template Method)用来定义算法的框架,将算法中的可变步骤定义为抽象方法,指定子类实现或重写。 1.1 角色 AbstractClass(…

字符串相关函数【超详细】(strcpy,strstr等string.h中的函数)

文章目录 strlen库中函数定义函数作用函数大概“工作”流程函数使用注意(要求)函数使用例举 strcpy库中函数定义函数作用函数使用注意(要求)函数大概“工作”流程函数使用例举 strcat库中函数定义函数作用函数使用注意&#xff08…

Go 的命令行解析 flag 包如何扩展新类型呢?

上篇文章 说到,除布尔类型 Flag,flag 支持的还有整型(int、int64、uint、uint64)、浮点型(float64)、字符串(string)和时长(duration)。 flag 内置支持能满足…

transformer和vit学习笔记

以下记录自己对transformer的学习笔记,可能自己看得懂【久了自己也忘了看不懂】,别人看起来有点乱。以后再优化文档~ 小伙伴请直接去看学习资源: Transformer的理解T-1_哔哩哔哩_bilibili 首先,时序处理:一些模型的出…

Two-factor authentication (2FA) is required for your GitHub account解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…