小林图解系统-四.内存管理 4.1 为什么要有虚拟内存?

虚拟内存

单片机没有操作系统,单片机的CPU是直接操作内存的物理地址

要想在内存中同时运行两个程序是不可能的。如果第一个程序在2000的位置写入一个新的值,将会擦掉第二个程序存放在相同位置上的所有内容,所以同时运行两个程序会立刻崩溃。

操作系统如何解决这个问题呢?

关键问题:这两个程序都引用了绝对物理地址,而正式我们需要避免的。

把进程所使用的地址[隔离]开来,让操作系统为每个进程分配独立的一套[虚拟地址],互不干涉。但是前提每个进程都不能访问物理地址,至于虚拟地址最终怎么落到物理内存里,对进程来说是透明的,操作系统已经把这些都安排了。

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

程序访问虚拟地址的时候,由操作系统转换成不同的物理地址,不同进程运行的时候,写入的是不同的物理地址。

我们程序所使用的内存地址叫做虚拟内存地址(Virtual Memory Address)

实际存在硬件里面的空间地址叫物理内存地址(Physial Memory Address)

操作系统引入了虚拟内存,进程持有的虚拟地址会通过CPU芯片的内存管理单元(MMU)的映射关系,来转换变成物理地址,然后再通过物理地址访问内存

操作系统是如何管理虚拟地址与物理地址之间的关系?.

内存分段和内存分页


内存分段

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

分段机制下,虚拟地址和物理地址是如何映射的?

段选择因子段内偏移量

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

知道了虚拟地址是通过段表与物理地址进行映射的,分段机制会把程序的虚拟地址分成4个段,每个段在段表中有一个项,在这一项找到段的基地址,加上偏移量,就找到物理内存的地址

分段解决了程序根本不需要关心具体的物理内存地址的问题,不足:

  • 内存碎片问题
  • 内存交换的效率低的问题

为什么会产生内存碎片?

退出的浏览器,变成两段分来的128内存。导致没有空间打开200MB的程序。

内存分段会出现内存碎片吗?

内部内存碎片+外部内存碎片

内存分段管理可以做到段根据实际需求分配内存,所以有多少需求就分配多大的段,不会出现内部内存碎片

由于每个段的长度不固定,多个段未必恰好使用所有的内存空间,会产生多个不连续的小物理内存,导致新的程序无法被加载,所以会出现外部内存碎片的问题。

解决外部内存碎片:内存交换

将音乐程序写到硬盘,在从硬盘读回到内存里。再读回就紧紧跟着已经被占用的内存。

内存交换空间,Swap空间,从硬盘划分出来的,用于内存与硬盘的空间交换。

分段为什么会导致内存交换效率低?

对于多进程系统,用分段的方式容易产生外部内存碎片,不得不重新Swap内存区域,会产生性能瓶颈。

硬盘访问太慢,每次交换都要大量内存数据写到硬盘上,所以内存交换的时候,如果是一个占内存空间很大的程序,整个机器都会卡顿

内存分页

分段的好处:能产生连续空间。不足,会出现[外部内存碎片和内存交换的空间太大导致卡顿]

少出现一些内存碎片,当需要内存交换的时候,让需要交换写入或者磁盘装载的数据更少一点,就可以解决问题了。

分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小。

页表储存在内存里,内存管理单元MMU做将虚拟内存地址转换成物理地址的工作。

当进程访问的虚拟地址在页表查不到,系统会缺页异常,进入内核空间物理内存、更新进程页表,最后再返回用户空间,恢复进程的运行。

分页是怎么解决[外部内存碎片和内存交换效率低]的问题?

内存分页由于内存空间是预先划分好的,不会像内存分段产生小的内存间隙。采用分页,页与页之间是紧密排列的,所以不会有外部碎片。

程序不足一页,也要分配一页,产生内存分页机制会有内部内存碎片的现象

如果内存空间不够,操作系统会把其他正在运行的进程中的[最近没使用]的内存页面注释掉,暂时写在硬盘里,成为[换出](Swap out)。需要的时候,再加载进来,称为换入(Swap In)

所以,一次性写入磁盘的也只有少数的一页或者几页,内存交换的效率就会高。

分页不需要一次性把程序都加载到物理内存,用页映射后,并不真的把页加载到物理内存。

只有程序运行中,需要用到对应虚拟内存页里面的指令和数据时,再加载到物理内存里面去。

分页机制,虚拟地址和物理地址如何映射?

页号:页表索引,页表包含物理页每页在物理内存的基地址

业内偏移

对于一个内存地址转换,三个步骤:

  • 把虚拟内存地址,切分成页号和偏移量
  • 根据页号,从页表里面,查询对应的物理页号
  • 直接拿物理页号,加上前面的偏移量,就得到了物理内存地址。

分页的缺点?

操作系统多进程同时运行,导致页表庞大

32位,虚拟内存4GB,每个页4kb(2^12),需要100万个页(2^20),每个页表项需要4个字节大小存储,4GB空间需要4MB

但是每个进程有自己的虚拟地址空间,100个进程有400MB

多级页表

局部性原理

如果某个一级页表的页表项没有被用到,也就不需要创建这个页表项对应的二级页表了,即可以在需要时才创建二级页表。

页表一定要覆盖全部虚拟地址空间,不分级的页表就需要有 100 多万个页表项来映射,而二级分页则只需要 1024 个页表项(此时一级页表覆盖到了全部虚拟地址空间,二级页表在需要时创建)。

推广到多级页表

64位系统,四级目录

全局页目录项PGD(Page Global Directory)

上层页目录项PUD(Page Upper Directory)

中间页目录项PMD(Page Middle Directory)

页表项PTE(Page Table Entry)

TLB

多级页表解决空间问题,但虚拟地址到物理地址的转换多了几道转换的工序,显然降低了地址转换的速度,也就是带来了时间上的开销。

程序有局部性,一段时间仅执行一部分,执行所访问的存储空间也局限于某个内存区域

利用此,把常访问的几个页表项存到访问速度更快的硬件,在CPU中加入了一个专门存放最常访问页表项的Cache:TLB(Translation Lookaside Buffer),称为:页表缓存,转址旁路缓存、快表

内存管理单元(Memory Management Unit)完成地址转换和TLB访问和交互

CPU寻址先找TLB,没有在继续查常规页表。


段页式内存管理

分页+分段组合。

  • 先将程序划分为多个有逻辑意义的段
  • 每个段划分多个页

地址结构:段号+段内页号+页内位移


Linux内存布局

Linux采用那种方式管理内存?

Intel 处理器80286-段式内存管理-->80386-页式内存管理

页式内存管理的作用是在由段式内存管理所映射而成的地址上再加一层地址映射。

  • 程序所使用的地址,通常是没被没内存管理映射的地址,称为逻辑地址
  • 通过段式内存管理映射的地址,称为线性地址,也叫虚拟地址

Linux 内存主要采用的是页式内存管理,但同时也不可避免地涉及了段机制

Linux 系统中的每个段都是从 0 地址开始的整个 4GB 虚拟空间(32 位环境下),也就是所有的段的起始地址都是一样的。这意味着,Linux 系统中的代码,包括操作系统本身的代码和应用程序代码,所面对的地址空间都是线性地址空间(虚拟地址),这种做法相当于屏蔽了处理器中的逻辑地址概念,段只被用于访问控制和内存保护。

Linux的虚拟地址空间如何分布?

内核空间+用户空间

每个进程都有独立的虚拟内存,但是每个虚拟内存中的内核地址,其实关联的都是相同的物理内存。


总结

为了在多进程环境下,使得进程之间的内存地址不受影响,相互隔离,于是操作系统就为每个进程独立分配一套虚拟地址空间,每个程序只关心自己的虚拟地址就可以,实际上大家的虚拟地址都是一样的,但分布到物理地址内存是不一样的。作为程序,也不用关心物理地址的事情。

每个进程都有自己的虚拟空间,而物理内存只有一个,所以当启用了大量的进程,物理内存必然会很紧张,于是操作系统会通过内存交换技术,把不常使用的内存暂时存放到硬盘(换出),在需要的时候再装载回物理内存(换入)。

那既然有了虚拟地址空间,那必然要把虚拟地址「映射」到物理地址,这个事情通常由操作系统来维护。

那么对于虚拟地址与物理地址的映射关系,可以有分段分页的方式,同时两者结合都是可以的。

内存分段是根据程序的逻辑角度,分成了栈段、堆段、数据段、代码段等,这样可以分离出不同属性的段,同时是一块连续的空间。但是每个段的大小都不是统一的,这就会导致外部内存碎片和内存交换效率低的问题。

于是,就出现了内存分页,把虚拟空间和物理空间分成大小固定的页,如在 Linux 系统中,每一页的大小为 4KB。由于分了页后,就不会产生细小的内存碎片,解决了内存分段的外部内存碎片问题。同时在内存交换的时候,写入硬盘也就一个页或几个页,这就大大提高了内存交换的效率。

再来,为了解决简单分页产生的页表过大的问题,就有了多级页表,它解决了空间上的问题,但这就会导致 CPU 在寻址的过程中,需要有很多层表参与,加大了时间上的开销。于是根据程序的局部性原理,在 CPU 芯片中加入了 TLB,负责缓存最近常被访问的页表项,大大提高了地址的转换速度。

Linux 系统主要采用了分页管理,但是由于 Intel 处理器的发展史,Linux 系统无法避免分段管理。于是 Linux 就把所有段的基地址设为 0,也就意味着所有程序的地址空间都是线性地址空间(虚拟地址),相当于屏蔽了 CPU 逻辑地址的概念,所以段只被用于访问控制和内存保护。

另外,Linux 系统中虚拟空间分布可分为用户态内核态两部分,其中用户态的分布:代码段、全局变量、BSS、函数栈、堆内存、映射区。

最后,说下虚拟内存有什么作用?

  • 第一,虚拟内存可以使得进程对运行内存超过物理内存大小,因为程序运行符合局部性原理,CPU 访问内存会有很明显的重复访问的倾向性,对于那些没有被经常使用到的内存,我们可以把它换出到物理内存之外,比如硬盘上的 swap 区域。
  • 第二,由于每个进程都有自己的页表,所以每个进程的虚拟内存空间就是相互独立的。进程也没有办法访问其他进程的页表,所以这些页表是私有的,这就解决了多进程之间地址冲突的问题。
  • 第三,页表里的页表项中除了物理地址之外,还有一些标记属性的比特,比如控制一个页的读写权限,标记该页是否存在等。在内存访问方面,操作系统提供了更好的安全性。

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

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

相关文章

远程桌面修改端口号后无法连接,怎么解决

远程桌面连接让用户在不同地点,不同设备上远程控制一台计算机,很大程度上节约了用户的成本并且提高了办公的灵活性和高效性。有时候修改了端口号就会连接不上,那该怎么办呢? 1. 检查本地计算机和远程计算机是否都连接了网络且网…

《精通嵌入式Linux编程》——解锁嵌入式Linux开发的无限可能

文章目录 📑前言一、书籍概览与作者风采二、内容详解与特色亮点2.1 嵌入式Linux基础与入门2.2 系统编程与内核探索2.3 驱动开发与实战演练2.4 内存管理与性能优化2.5 系统调试与性能提升2.6 综合项目实践与案例分析 三、书籍价值与应用展望 📑前言 在当今…

利用反向代理编写HTTP抓包工具——可视化界面

手写HTTP抓包工具——可视化界面 项目描述语言golang可视化fynev2功能代理抓包、重发、记录 目录 1. 示例1.1 主界面1.2 开启反向代理1.3 抓包1.4 历史记录1.5 重发 2. 核心代码2.1 GUI2.1 抓包 3. 结语3.1 传送门 1. 示例 1.1 主界面 1.2 开启反向代理 1.3 抓包 1.4 历史记录…

国产32位高精度低功耗DSP音频处理芯片-DU561

DU561是一款集成多种音效算法高性能32位DSP音频处理芯片;具有高速、高精度、高稳定性等特点,能实现对音频信号的滤波、增强、降噪、混响、变调等处理,广泛应用于音频系统、通信系统、汽车音响、家庭影院、舞台设备等领域。 音频处理可以更好地…

ShuffleNet系列论文阅读笔记(ShuffleNetV1和ShuffleNetV2)

目录 ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices摘要Approach—方法Channel Shuffle for Group Convolutions—用于分组卷积的通道重排ShuffleNet Unit—ShuffleNet单元Network Architecture—网络体系结构 总结 ShuffleNet V2: Pra…

工业无线网关在实际生产中的应用效果和价值-天拓四方

随着智能制造的快速发展,工业无线网关作为关键通信设备,在提升生产效率、优化生产流程、实现设备间的互联互通等方面发挥着越来越重要的作用。以下是一个关于工业无线网关在智能制造行业应用的具体案例,展示了其在实际生产中的应用效果和价值…

toLocaleString浏览器兼容问题,导致时间在不同版本显示24/12小时制

先看toLocaleString结果区别 旧版 新版 问题原因 Google Chrome 和其他浏览器会定期更新,这些更新可能包括对 JavaScript 引擎和国际化的改进较新版本的 Chrome(版本 125.0.6422.142)已经更新了其国际化实现,以默认使用24小时制 …

SpringBoot整合justauth实现多种方式的第三方登陆

目录 0.准备工作 1.引入依赖 2.yml文件 3. Controller代码 4.效果 参考 0.准备工作 你需要获取三方登陆的client-id和client-secret 以github为例 申请地址&#xff1a;Sign in to GitHub GitHub 1.引入依赖 <?xml version"1.0" encoding"UTF-8&quo…

NAT Easyip实验

我们这篇博客将重点讲述easy ip的配置&#xff1a; 以下面的一个简单的实验拓扑图为例&#xff1a; 本实验使用的网络地址&#xff1a; 1. 我们先来完成基础配置&#xff1a; 1.1AR1的基础配置&#xff1a; 1.2AR2上的基础配置 1.3完成AR1和AR2的基础配置后&#xff0c;我们…

【SPIE出版】第六届无线通信与智能电网国际会议(ICWCSG 2024,7月26-28)

随着科技的飞速发展和能源需求的日益增长&#xff0c;智能电网技术逐渐成为电力行业的重要发展方向。与此同时&#xff0c;无线通信技术在近年来也取得了显著的进步&#xff0c;为智能电网的发展提供了强有力的支持。为了进一步推动无线通信与智能电网的结合与发展&#xff0c;…

Socket编程之多进程模型

一、多进程模型概述 基于最初的阻塞网络 I/O &#xff0c;若服务器要为多个客户端提供支持&#xff0c;在较为传统的手段中&#xff0c;多进程模型是常用的选择&#xff0c;即为每个客户端都分配一个进程来处理其请求。 服务器的主进程主要负责对客户连接的监听&#xff0c;一旦…

视频云沉浸式音视频技术能力探索与建设

概述 随着传输技术、显示技术与算力的持续提升&#xff0c;用户对于音视频体验的需求在提高&#xff0c;各家设备厂商也在探索和推出对应的技术与产品。打造空间感的空间视频与空间音频是其中最为关键的2项技术&#xff0c;bilibili视频云在这两项技术领域也进行了相关代探索与…

redis.conf 参数详解,方便进行性能优化配置

以下是redis.conf中一些常见参数的详细说明&#xff1a; daemonize&#xff1a;是否以后台进程运行&#xff0c;默认为no&#xff1b; pidfile&#xff1a;如以后台进程运行&#xff0c;则需指定一个pid&#xff0c;默认为/var/run/redis.pid&#xff1b;bind&#xff1a;绑定主…

WPF——属性

一、属性 类最初只有字段与函数&#xff0c;字段为一个变量&#xff0c;访问权限可以是private&#xff0c;protected&#xff0c;public。而将字段设为private&#xff0c;不方便外界对类数据的操作&#xff0c;但是将字段设为public又怕外界对数据进行非法操作&#xff0c;于…

二叉树-二叉搜索树的最近公共祖先

目录 一、问题描述 二、解题思路 三、代码实现 四、刷题链接 一、问题描述 二、解题思路 这个问题和之前做过的问题很相似&#xff1a; 深度优先遍历-在二叉树中找到两个节点的最近公共祖先-CSDN博客文章浏览阅读80次。java刷题&#xff1a;在二叉树中找到两个结点的最近公…

用于快速充电站的 AC/DC 转换器概述

电动汽车构成了未来实现可持续交通部门的有前途技术的主要部分。AC/DC 转换器是扩展和改进 EV 功能的骨干组件。本文概述了 AC/DC 转换器、充电站类型、传统两电平 (2L) AC/DC 转换器面临的问题以及使用多电平转换器 (MLC) 的重要性。 AC/DC 充电器示意图&#xff08;&#xff…

2024广东省职业技能大赛云计算赛项实战——Minio服务搭建

Minio服务搭建 前言 这道题是比赛时考到的&#xff0c;没找到具体题目&#xff0c;但在公布的样题中找到了&#xff0c;虽然很短~ 使用提供的 OpenStack 云平台&#xff0c;申请一台云主机&#xff0c;使用提供的软件包安装部署 MINIO 服务并使用 systemctl 管理 Minio是一个…

关于接口测试——自动化框架的设计与实现

一、自动化测试框架 在大部分测试人员眼中只要沾上“框架”&#xff0c;就感觉非常神秘&#xff0c;非常遥远。大家之所以觉得复杂&#xff0c;是因为落地运用起来很复杂&#xff1b;每个公司&#xff0c;每个业务及产品线的业务流程都不一样&#xff0c;所以就导致了“自动化…

Linux_理解进程地址空间和页表

目录 1、进程地址空间示意图 2、验证进程地址空间的结构 3、验证进程地址空间是虚拟地址 4、页表-虚拟地址与物理地址 5、什么是进程地址空间 6、进程地址空间和页表的存在意义 6.1 原因一&#xff08;效率性&#xff09; 6.2 原因二&#xff08;安全性&#xff09; …