内存管理问题总结
内存管理
虚拟内存
我们程序所使⽤的内存地址叫做虚拟内存地址(Virtual Memory Address)
实际存在硬件⾥⾯的空间地址叫物理内存地址(Physical Memory Address)
操作系统引⼊了虚拟内存,进程持有的虚拟地址会通过 CPU 芯⽚中的内存管理单元(MMU)的映射关
系,来转换变成物理地址,然后再通过物理地址访问内存
1.操作系统是如何管理虚拟地址与物理地址之间的关系?
主要有两种⽅式,分别是内存分段和内存分⻚,分段是⽐较早提出的,我们先来看看内存分段。
程序是由若⼲个逻辑分段组成的,如可由代码分段、数据分段、栈段、堆段组成。不同的段是有不同的属
性的,所以就⽤分段segmentation的形式把这些段分离出来。

2.分段机制下,虚拟地址和物理地址是如何映射的?
分段机制下的虚拟地址由两部分组成,段选择⼦和段内偏移量

段选择⼦就保存在段寄存器⾥⾯。段选择⼦⾥⾯最重要的是段号,⽤作段表的索引。段表⾥⾯保存的
是这个段的基地址、段的界限和特权等级等。
虚拟地址中的段内偏移量应该位于 0 和段界限之间,如果段内偏移量是合法的,就将段基地址加上段
内偏移量得到物理内存地址。
知道了虚拟地址是通过段表与物理地址进⾏映射的,分段机制会把程序的虚拟地址分成 4 个段,每个段在段表中有⼀个项,在这⼀项找到段的基地址,再加上偏移量,于是就能找到物理内存中的地址,
分段的办法很好,解决了程序本身不需要关⼼具体的物理内存地址的问题,但它也有⼀些不⾜之处:
第⼀个就是内存碎⽚的问题。
第⼆个就是内存交换的效率低的问题。
解决外部内存碎⽚的问题就是内存交换。这个内存交换空间,在 Linux 系统⾥,也就是我们常看到的 Swap 空间,这块空间是从硬盘划分出来的,⽤于内存与硬盘的空间交换。
3.分段为什么会导致内存交换效率低的问题?
对于多进程的系统来说,⽤分段的⽅式,内存碎⽚是很容易产⽣的,产⽣了内存碎⽚,那不得不重新
Swap 内存区域,这个过程会产⽣性能瓶颈。因为硬盘的访问速度要⽐内存慢太多了,每⼀次内存交换,我们都需要把⼀⼤段连续的内存数据写到硬盘
上。所以,如果内存交换的时候,交换的是⼀个占内存空间很⼤的程序,这样整个机器都会显得卡顿。
要解决这些问题,那么就要想出能少出现⼀些内存碎⽚的办法。另外,当需要进⾏内存交换的时候,让需
要交换写⼊或者从磁盘装载的数据更少⼀点,这样就可以解决问题了。这个办法,也就是内存分⻚
(Paging)。
分⻚是把整个虚拟和物理内存空间切成⼀段段固定尺⼨的⼤⼩。这样⼀个连续并且尺⼨固定的内存空间,
我们叫⻚(Page)。在 Linux 下,每⼀⻚的⼤⼩为 4KB 。
虚拟地址与物理地址之间通过⻚表来映射,如下图:

⻚表是存储在内存⾥的,内存管理单元 (MMU)就做将虚拟内存地址转换成物理地址的⼯作
⽽当进程访问的虚拟地址在⻚表中查不到时,系统会产⽣⼀个缺⻚异常,进⼊系统内核空间分配物理内
存、更新进程⻚表,最后再返回⽤户空间,恢复进程的运⾏。更进⼀步地,分⻚的⽅式使得我们在加载程序的时候,不再需要⼀次性都把程序加载到物理内存中。我们
完全可以在进⾏虚拟内存和物理内存的⻚之间的映射之后,并不真的把⻚加载到物理内存⾥,⽽是只有在
程序运⾏中,需要⽤到对应虚拟内存⻚⾥⾯的指令和数据时,再加载到物理内存⾥⾯去。
4.分⻚是怎么解决分段的内存碎⽚、内存交换效率低的问题?
由于内存空间都是预先划分好的,也就不会像分段会产⽣间隙⾮常⼩的内存,这正是分段会产⽣内存碎⽚
的原因。⽽采⽤了分⻚,那么释放的内存都是以⻚为单位释放的,也就不会产⽣⽆法给进程使⽤的⼩内
存。
如果内存空间不够,操作系统会把其他正在运⾏的进程中的「最近没被使⽤」的内存⻚⾯给释放掉,也就
是暂时写在硬盘上,称为换出(Swap Out)。⼀旦需要的时候,再加载进来,称为换⼊(Swap In)。所
以,⼀次性写⼊磁盘的也只有少数的⼀个⻚或者⼏个⻚,不会花太多时间,内存交换的效率就相对⽐较
⾼。

更进⼀步地,分⻚的⽅式使得我们在加载程序的时候,不再需要⼀次性都把程序加载到物理内存中。我们
完全可以在进⾏虚拟内存和物理内存的⻚之间的映射之后,并不真的把⻚加载到物理内存⾥,⽽是只有在
程序运⾏中,需要⽤到对应虚拟内存⻚⾥⾯的指令和数据时,再加载到物理内存⾥⾯去。
5.分⻚机制下,虚拟地址和物理地址是如何映射的?
在分⻚机制下,虚拟地址分为两部分,⻚号和⻚内偏移。⻚号作为⻚表的索引,⻚表包含物理⻚每⻚所在
物理内存的基地址,这个基地址与⻚内偏移的组合就形成了物理内存地址,⻅下图。

总结⼀下,对于⼀个内存地址转换,其实就是这样三个步骤:
把虚拟内存地址,切分成⻚号和偏移量;
根据⻚号,从⻚表⾥⾯,查询对应的物理⻚号;
直接拿物理⻚号,加上前⾯的偏移量,就得到了物理内存地址
6.简单的分⻚有什么缺陷吗?
有空间上的缺陷。
因为操作系统是可以同时运⾏⾮常多的进程的,那这不就意味着⻚表会⾮常的庞⼤。
在 32 位的环境下,虚拟地址空间共有 4GB,假设⼀个⻚的⼤⼩是 4KB(2^12),那么就需要⼤约 100 万
(2^20) 个⻚,每个「⻚表项」需要 4 个字节⼤⼩来存储,那么整个 4GB 空间的映射就需要有 4MB
的内存来存储⻚表。
这 4MB ⼤⼩的⻚表,看起来也不是很⼤。但是要知道每个进程都是有⾃⼰的虚拟地址空间的,也就说都有
⾃⼰的⻚表。那么, 100 个进程的话,就需要 400MB 的内存来存储⻚表,这是⾮常⼤的内存了,更别说 64 位的环
境了。
要解决上⾯的问题,就需要采⽤⼀种叫作多级⻚表(Multi-Level Page Table)的解决⽅案。
多级⻚表虽然解决了空间上的问题,但是虚拟地址到物理地址的转换就多了⼏道转换的⼯序,这显然就降
低了这俩地址转换的速度,也就是带来了时间上的开销。
程序是有局部性的,即在⼀段时间内,整个程序的执⾏仅限于程序中的某⼀部分。相应地,执⾏所访问的
存储空间也局限于某个内存区域。
我们就可以利⽤这⼀特性,把最常访问的⼏个⻚表项存储到访问速度更快的硬件,于是计算机科学家们,
就**在 CPU 芯⽚中,**加⼊了⼀个专⻔存放程序最常访问的⻚表项的 Cache,这个 Cache 就是 TLB
==(Translation Lookaside Buffer) ,==通常称为⻚表缓存、转址旁路缓存、快表等。

在 CPU 芯⽚⾥⾯,封装了内存管理单元(Memory Management Unit)芯⽚,它⽤来完成地址转换和 TLB
的访问与交互。
有了 TLB 后,那么 CPU 在寻址时,会先查 TLB,如果没找到,才会继续查常规的⻚表。
TLB 的命中率其实是很⾼的,因为程序最常访问的⻚就那么⼏个。
7.Intel 处理器的内存管理发展历史。
早期 Intel 的处理器从 80286 开始使⽤的是段式内存管理。但是很快发现,光有段式内存管理⽽没有⻚式
内存管理是不够的,这会使它的 X86 系列会失去市场的竞争⼒。因此,在不久以后的 80386 中就实现了对
⻚式内存管理。也就是说,80386 除了完成并完善从 80286 开始的段式内存管理的同时还实现了⻚式内存
管理。
但是这个 80386 的⻚式内存管理设计时,没有绕开段式内存管理,⽽是建⽴在段式内存管理的基础上,这
就意味着,⻚式内存管理的作⽤是在由段式内存管理所映射⽽成的地址上再加上⼀层地址映射。
由于此时由段式内存管理映射⽽成的地址不再是“物理地址”了,Intel 就称之为“线性地址”(也称虚拟地
址)。于是,段式内存管理先将逻辑地址映射成线性地址,然后再由⻚式内存管理将线性地址映射成物理
地址。

这⾥说明下逻辑地址和线性地址:
程序所使⽤的地址,通常是没被段式内存管理映射的地址,称为逻辑地址;
通过段式内存管理映射的地址,称为线性地址,也叫虚拟地址;
逻辑地址是「段式内存管理」转换前的地址,线性地址则是「⻚式内存管理」转换前的地址。
8.Linux 采⽤了什么⽅式管理内存?
Linux 内存主要采⽤的是⻚式内存管理,但同时也不可避免地涉及了段机制。
这主要是上⾯ Intel 处理器发展历史导致的,因为 Intel X86 CPU ⼀律对程序中使⽤的地址先进⾏段式映
射,然后才能进⾏⻚式映射。既然 CPU 的硬件结构是这样,Linux 内核也只好服从 Intel 的选择。
但是事实上,Linux 内核所采取的办法是使段式映射的过程实际上不起什么作⽤。也就是说,“上有政策,
下有对策”,若惹不起就躲着⾛。
Linux 系统中的每个段都是从 0 地址开始的整个 4GB **虚拟空间(**32 位环境下),也就是所有的段的起始
**地址都是⼀样的。这意味着,**Linux 系统中的代码,包括操作系统本身的代码和应⽤程序代码,所⾯对的
地址空间都是线性地址空间(虚拟地址),这种做法相当于屏蔽了处理器中的逻辑地址概念,段只被⽤于
访问控制和内存保护。
9.Linux 的虚拟地址空间是如何分布的?
在 Linux 操作系统中,虚拟地址空间的内部⼜被分为内核空间和⽤户空间两部分,不同位数的系统,地址
空间的范围也不同。⽐如最常⻅的 32 位和 64 位系统,如下所示:

通过这⾥可以看出:
32 位系统的内核空间占⽤ 1G ,位于最⾼处,剩下的 3G 是⽤户空间;
64 位系统的内核空间和⽤户空间都是 128T ,分别占据整个内存空间的最⾼和最低处,剩下的中
间部分是未定义的
,内核空间与⽤户空间的区别:
进程在⽤户态时,只能访问⽤户空间内存;
只有进⼊内核态后,才可以访问内核空间的内存;虽然每个进程都各⾃有独⽴的虚拟内存,但是每个虚拟内存中的内核地址,其实关联的都是相同的物理内
存。这样,进程切换到内核态后,就可以很⽅便地访问内核空间内存。

进⼀步了解虚拟空间的划分情况,⽤户空间和内核空间划分的⽅式是不同的,内核空间的分布情
况就不多说了。
我们看看⽤户空间分布的情况,以 32 位系统为例,我画了⼀张图来表示它们的关系:

⽤户空间内存,从低到⾼分别是 7 种不同的内存段:
程序⽂件段,包括⼆进制可执⾏代码;
已初始化数据段,包括静态常量;
未初始化数据段,包括未初始化的静态变量;
堆段,包括动态分配的内存,从低地址开始向上增⻓;
⽂件映射段,包括动态库、共享内存等,从低地址开始向上增⻓(跟硬件和内核版本有关);
栈段,包括局部变量和函数调⽤的上下⽂等。栈的⼤⼩是固定的,⼀般是 8 MB 。当然系统也提供
了参数,以便我们⾃定义⼤⼩;在这 7 个内存段中,堆和⽂件映射段的内存是动态分配的。⽐如说,使⽤ C 标准库的 malloc() 或者
mmap() ,就可以分别在堆和⽂件映射段动态分配内存。
相关文章:

内存管理问题总结
内存管理 虚拟内存 我们程序所使⽤的内存地址叫做虚拟内存地址(Virtual Memory Address) 实际存在硬件⾥⾯的空间地址叫物理内存地址(Physical Memory Address) 操作系统引⼊了虚拟内存,进程持有的虚拟地址会通过 …...

十七、Intellij IDEA2022.1.1下载、安装、激活
目录 🌻🌻 一、下载二、 安装三、激活 一、下载 官网下载地址 本地直接下载 目前Intellij IDEA的最新版本已经更新到了 2024.1.4,由于最新版本可能存在不稳定的问题,此处选择其他版本进行下载,此处以2022.1.1为例进行下…...

【Material-UI】Button Group 中的 Disabled Elevation 功能
文章目录 一、Button Group 组件概述二、什么是 Elevation?三、为什么需要禁用 Elevation?四、使用 disableElevation 属性五、属性解析1. disableElevation 属性2. variant 属性3. aria-label 属性 六、应用场景1. 表单操作2. 工具栏3. 导航按钮 七、样…...
Java RESTful API 测试:使用 RestAssured
Java RESTful API 测试:使用 RestAssured 简介 在现代软件开发中,RESTful API扮演着至关重要的角色。API的测试同样重要以确保它们按预期工作。Java中的RestAssured库提供了一种简单直观的方式来测试RESTful Web服务。本文将介绍RestAssured的基本概念…...
将nestjs项目迁移到阿里云函数
注意:长耗时,高内存 的应用,定时任务 不适合迁移。 根据模板创建项目 一、模板配置修改 1.node版本修改 由于我的nestjs项目是node18的需要修改 pre-deploy项目: 改成 resources:framework:component: fc3actions:pre-deploy:-…...
边缘计算×AI:绘制未来实时智能的宏伟蓝图
引言:时代的召唤 随着物联网技术的飞速发展,数以亿计的传感器和智能设备正不断涌入我们的生活和工作空间,它们生成的数据量级之大,远非传统的集中式云处理所能高效应对。因此,一种新兴的数据处理模式——边缘计算&…...

实现关系运算符的重载
全局函数的实现法: 成员函数实现法:...

【css】使用CSS绘制奥运五环--巴黎奥运
使用CSS绘制奥运五环 在2024年巴黎奥运会期间,本文来使用 CSS 来画一个奥运五环。奥运五环由五个相互交叠的圆环组成,分别代表五大洲。 奥运五环是相互连接的,因此在视觉上会产生重叠效果,这也是实现五环最有挑战性的部分 HTML结…...
【Python数据处理】MatplotlibNumpyPandas常用API整理
目录 Matplotlib 1. 导入 Matplotlib 并创建图布 2. 实现基础绘图 2.1 折线图 2.2 柱状图 2.3 散点图 2.4 直方图 3. 完善绘图辅助功能 3.1 添加标题和标签 3.2 添加网格线 3.3 添加图例 4. 在一个坐标系下绘制多个图像 5. 在一个图形窗口创建多个子图 5.1 使用 a…...
Nacos是阿里巴巴开源的一款分布式服务注册中心和配置中心
Nacos是阿里巴巴开源的一款分布式服务注册中心和配置中心,旨在帮助开发人员更轻松地构建和管理微服务架构。以下是关于Nacos的详细介绍: 一、概述 Nacos是Dynamic Naming and Configuration Service(动态命名和配置服务)的缩写&a…...

条形码与二维码报表
概述 条形码与二维码:演示条形码与二维码,条形码数据将来自于关联的字段值。支持各种常用的条形码与二维码。 应用场景 如下图所示,简单展示数据 示例说明 数据准备 在数据面板中添加数据集,可选择Json数据集和API服务数据…...
数据采集工具之Flume
本文主要实现数据到datahub的采集过程 1、下载 Index of /dist/flume/1.11.0 datahub插件下载 https://aliyun-datahub.oss-cn-hangzhou.aliyuncs.com/tools/aliyun-flume-datahub-sink-2.0.9.tar.gz 2、安装 $ tar aliyun-flume-datahub-sink-x.x.x.tar.gz $ cd aliyun-…...

【24年最新】AI大模型零基础入门到精通学习资料大全,学完你就是LLM大师!
零基础如何学习大模型 AI 领取方式在文末 为什么要学习大模型? 学习大模型课程的重要性在于它能够极大地促进个人在人工智能领域的专业发展。大模型技术,如自然语言处理和图像识别,正在推动着人工智能的新发展阶段。通过学习大模型课程&am…...
使用RabbitMQ死信交换机实现延迟消息
文章目录 什么是死信交换机?死信交换机实现延迟消息的思路实现过程配置类消费者监听死信队列发送延迟消息 注意事项总结 在开发过程中,我们常常会遇到需要延迟处理某些消息的场景,例如订单的支付超时处理、短信的定时发送等。本文将介绍如何使…...

overleaf上latex表格的使用,latex绘制三线表
三线表需要的包、代码及其示例解释。 一般需要用到的包: \usepackage{tabu} % 表格插入 \usepackage{multirow} % 一般用以设计表格,将所行合并 \usepackage{multicol} % 合并多列 \usepackage{m…...

聚焦光热型太阳光模拟器助力多晶硅均匀加热
晶圆均匀加热技术综述 晶圆均匀加热是半导体制造过程中的关键技术之一,直接影响着晶圆上各种加工工艺的质量和稳定性。晶圆加热的目的在于化学气相沉积、退火、氧化等工艺中,通过对晶圆进行必要的热处理,以促进或优化后续工艺步骤。不均匀的…...

【Android】四大组件(Activity、Service、Broadcast Receiver、Content Provider)、结构目录
文章目录 Android系统架构Android四大组件ActivityServiceBroadcast ReceiverContent Provider 两大视图主要结构目录 Android系统架构 https://blog.csdn.net/xzzteach/article/details/140904613 Android四大组件 Activity 一个 Activity 包含了用户能够看到的界面࿰…...
前端开发:创建可拖动的固定位置 `<div>` 和自动隐藏悬浮按钮
在前端开发中,实现一个可拖动的固定位置 <div>,并且根据拖动的状态控制其显示和隐藏,同时在特定条件下显示悬浮按钮,涉及以下技术和原理: 技术细节和实现步骤: 1. HTML 结构: <!DOC…...
Java Bean Validation 注解:@NotEmpty、@NotBlank 和 @NotNull 的区别
1. 概述 Bean Validation 是 Java 提供的一种对 Java Bean 实例的字段或方法参数进行校验的标准机制。它允许开发者使用注解的方式定义验证逻辑,这些注解可以在类、字段或者方法上声明,并且可以被任何实现了 JSR 303/JSR 349 规范的框架(如 …...

Java | Leetcode Java题解之第322题零钱兑换
题目: 题解: public class Solution {public int coinChange(int[] coins, int amount) {int max amount 1;int[] dp new int[amount 1];Arrays.fill(dp, max);dp[0] 0;for (int i 1; i < amount; i) {for (int j 0; j < coins.length; j)…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...