大厨的工作台与计算机内存:搞懂操作系统内存管理

本文让我们一起来了解下操作系统的内存管理。

大厨的工作台

我们可以把计算机看作是一个大厨,而内存就像大厨的工作台。大厨在烹饪过程中,需要将食材和工具放在工作台上,这样就可以直接访问和使用。计算机也是一样,它需要将正在运行的程序和数据放在内存中,才能进行快速的读写操作。

内存是CPU可以直接访问的存储,其操作速度很快。我们在编程时,需要经常与内存打交道,开发者喜欢把各种数据放到内存中,用起来比较方便,但是如果重启电脑,内存中的数据就会丢失,而且内存空间相比硬盘等外置存储的空间会小很多,使用的时候也需要注意。因此,我们需要很好的理解内存的工作原理,如此才能更好地进行编程。

实模式:混用工作台的问题

那么,CPU是如何操作内存的呢?首先,让我们来看看最早出现的实模式。

实模式就像是一个大工作台,所有的软件,包括操作系统,都在同一个物理地址空间,就像所有的菜品的食材和工具都放在工作台上。

在实模式下,CPU会提供一个软中断,并在中断向量表中关联内存管理函数,当软件需要内存时,就会触发这个软中断,执行内存管理函数,分配物理内存空间。

中断是CPU提供的一个机制,用于处理一些突发情况或需要尽快响应的事件,当CPU收到中断信号时,它会停止处理当前的工作,然后根据中断事件执行相关的程序,最后再回来执行之前的事务。中断分为硬中断和软中断,硬中断是硬件触发的,比如网卡接收到数据后通过中断通知CPU进行处理,软中断是软件程序触发的,比如应用程序通过操作系统API读取文件时会触发软中断,以执行操作系统内核中的文件读取函数。

中断向量表定义了中断事件和相应处理程序的映射关系,CPU收到中断事件后,可以在中断向量表中根据事件编号找到对应的处理程序地址,然后执行这个处理程序。

在实模式下,执行外置存储(如硬盘)中的软件,需要将软件完整地从外置存储读取到内存,然后确定软件中数据和函数的浮动地址。这就像你在做饭时,需要使用到某个工具,就会打开抽屉,找到它,然后放到工作台上,供后续使用。

但是,实模式存在一些问题。

  • 首先,所有软件在同一个物理地址空间,就像是住在一个大家庭里,每个人都可以访问到其他人的东西,这就容易出现问题,比如数据被错误地修改,或者被恶意破坏。
  • 其次,实模式下的内存利用率问题也很严重。因为软件需要完整地加载到内存,代码量越多需要的内存越多,就像是你在做饭时,工作台上放得越满,可用的空间就越少。

这就像炒菜时因为所有的东西都放在了一起,导致混用了不同菜品的佐料,而且如果要把所有的东西都放到台面上,就需要很大的空间才行,而很多东西可能一段时间都用不上,这就比较浪费了。

由上可见,实模式就是实实在在的使用物理内存,软件声明多少空间就得分配多少空间,而且软件之间相互没有限制。

保护模式:分时共享的方案

为了解决实模式的问题,就有了保护模式。在保护模式下,每个软件都有自己的虚拟内存空间,这些空间可以映射到物理内存,这种映射有两个特点:

  • 不是所有的虚拟内存空间都同时映射到物理内存,而是需要哪个虚拟内存空间的数据时才进行装载和映射,不需要时就卸载对应的物理空间、解除映射;
  • 这个映射也不是软件想怎么映射就怎么映射,它是由操作系统统一管理的,这就保护了软件的数据空间,这也是保护模式这个名字的来源。

这种模式,就像炒菜时,我们并不是把所有菜品的材料和工具都堆到工作台上,而是假设制作每个菜品时都会有足够的工作台空间,需要制作某个菜品时再把相关的材料和工具放到工作台上。这本质上是一种分时共享工作台的方案。

现在我们来看看保护模式的具体运作方式。在保护模式下,所有软件内存访问基于虚拟内存,虚拟内存空间分为很多个连续的内存页,这些页可以映射到物理内存。

  • 当CPU访问某个虚拟内存中的数据时,首先计算出内存页,然后在操作系统的地址映射表中找到物理内存页,然后操作数据。
  • 如果地址映射表中没有,则CPU会产生一个缺页中断请求,此时需要操作系统将数据从磁盘加载到物理内存,并做好与虚拟内存的映射。
  • 如果缺页时物理内存不足,则操作系统会淘汰长久没有访问的物理内存,释放出一些物理空间给新的需求。

在保护模式下,执行外置存储中的软件,操作系统会给软件分配一个很大的虚拟内存空间,需要哪个内存页时通过缺页中断加载到物理内存。

保护模式有很多的好处:

  • 解决了内存访问的安全问题,软件只能看到自己的虚拟空间,不能直接操作物理内存。
  • 提高了内存资源的利用率,操作系统可以把空闲程序使用的物理空间先给别的程序用。
  • 无需计算代码的浮动地址。软件认为自己独占所有内存,可以在编写程序或者编译程序时假设自己代码加载的绝对地址,不需要在加载到内存时再重新调整CPU指令操作的地址。
  • 避免了CPU直接访问外置存储,并去理解外置存储的细节,从而避免了耦合。

虚拟内存的有趣问题

关于虚拟内存还有一个有趣的问题:在固态硬盘还没有普及的年代,电脑会越用越慢,但是又不舍得换新机,然后聪明的同学就会把系统盘由机械硬盘换成固态硬盘,然后电脑操作速度又快了起来,又能再战几年。

这是为什么呢?

这和虚拟内存有很大的关系。操作系统会将部分暂时用不上的内存数据放到硬盘上,特别是当我们运行的所有程序的总数据量超过了物理内存的容量时,这在现在软件程序特别丰富的时代很容易出现,跑几个大型程序,物理内存可能就不够了;当程序需要运行时,如果发现虚拟内存对应的数据在硬盘上,操作系统又会把这些数据从硬盘加载到物理内存中。内存和硬盘的这种交互,称为交换(Swap)。

而硬盘的读写速度要比内存慢很多,特别是机械硬盘,使用时间久了,因为硬盘老化和磁盘碎片增多,速度会掉的比较多,交换操作就会变慢,特别是系统刚启动或者运行的程序比较多的时候,交换操作可能频繁发生,就会感觉电脑很慢很卡。而固态硬盘的读写速度要比机械硬盘快很多,所以换成固态硬盘,电脑甚至会比之前快很多。

分层思想放光芒

总的来说,操作系统的内存管理使用了一种分层的思想,通过增加虚拟内存这一层,解决了内存访问的安全问题,提高了内存资源的利用率,避免了软件加载时重新调整CPU指令操作的地址,也避免了CPU直接访问外置存储,并去理解外置存储的细节,从而避免了耦合。


希望通过这篇文章,你能对计算机的内存管理有更深入的理解,从而在编程时,更好地利用内存资源,提高程序的性能。记住,内存就像大厨的工作台,管理好它,就能烹饪出美味的菜肴。

关注微/信/公/众/号:萤火架构,提升技术不迷路。

相关推荐
萧萧玉树6 分钟前
分布式在线评测系统
前端·c++·后端·负载均衡
桃园码工24 分钟前
第一章:Go 语言概述 2.安装和配置 Go 开发环境 --Go 语言轻松入门
开发语言·后端·golang
Koishi_TvT1 小时前
蓝桥杯c++算法秒杀【6】之动态规划【下】(数字三角形、砝码称重(背包问题)、括号序列、异或三角:::非常典型的必刷例题!!!)
c语言·c++·算法·性能优化·蓝桥杯·动态规划·c
hummhumm1 小时前
第 36 章 - Go语言 服务网格
java·运维·前端·后端·python·golang·java-ee
凡人的AI工具箱1 小时前
40分钟学 Go 语言高并发:Pipeline模式(一)
开发语言·后端·缓存·架构·golang
南鸳6102 小时前
Scala:根据身份证号码,输出这个人的籍贯
开发语言·后端·scala
小扳2 小时前
微服务篇-深入了解使用 RestTemplate 远程调用、Nacos 注册中心基本原理与使用、OpenFeign 的基本使用
java·运维·分布式·后端·spring·微服务·架构
ᝰꫝꪉꪯꫀ3612 小时前
JavaWeb——SpringBoot原理
java·开发语言·后端·springboot
LLLibra1462 小时前
如何使用Postman优雅地进行接口自动加密与解密
后端
LightOfNight3 小时前
Redis设计与实现第14章 -- 服务器 总结(命令执行器 serverCron函数 初始化)
服务器·数据库·redis·分布式·后端·缓存·中间件