首先,问大家一个很有趣的问题,有人玩过单片机吗?有人用过 Excel 表格吗?

相信很多人都没有把玩过单片机,但是 Excel 倒是玩的贼溜,是不是?

没玩过单片机,哪听说过单片机有操作系统吗?能同时运行多个程序吗?

没吃过猪肉,还没见过猪跑么?单片机是没有操作系统的,也不能同时运行多个程序!

因为单片机都是把写好的程序直接烧录到设备中去,一旦烧录了,就不能更改,而且同时只能让运行一个程序,不能运行多个。因为,刀片机中的程序是直接操作物理内存的。

你可以脑补一下,如果同一个物理内存地址被多个程序同时使用,会出现什么情况?那画面,简直不可入脑。 脑壳痛!!!

而我们现在用的 windows 系列、类 unix 系列操作系统,‘智能’ 的为我们设计了一套内存管理机制 MMU。

每个进程一运行,就会给他分配一个虚拟内存 VM 空间,和在内存条中分配一段物理内存 PM 空间。虚拟内存里面的信息告诉进程,自己要用的内存数据,在物理内存哪些地方。

图解虚拟内存、物理内存、swap 分区的工作与管理_虚拟内存

 

每个进程都有分配自己的虚拟内存,虚拟内存中记录物理内存的位置信息,所以,每个进程的内存就被天然的隔离了,不会出现在内存条中,抢别的进程资源。

而一个进程要能正常运行,它的物理内存中,至少会包括:栈数据、堆数据、代码信息、数据信息,这些在物理内存中是分块存放的,也就是从某一个位置开始,连续一段空间,都是存着相同类型的数据,所以,虚拟内存中,要把这些数据的起始位和偏移量都存储好,这样,进程要使用某一类数据时,就能快速找到这类数据在内存中的位置,从而获取到数据。

图解虚拟内存、物理内存、swap 分区的工作与管理_物理内存_02

 

说了一大堆,可能还有很多人没有明白,下面,整点明白的。

你平时工作中,是不是要整很多 Excel 表格,存储各种工作信息,你要某些工作信息时,就打开这个 Excel 文件,这个文件中有很多个工作表,你要某些数据时,就点击工作表的名称,打开对应表格,查看对应数据。

图解虚拟内存、物理内存、swap 分区的工作与管理_物理内存_03

 

你可以把整个 Excel 文件,理解为进程运行需要的信息,每一个工作表名称,就相当于虚拟内存,告诉我们,需要的具体数据在哪儿?每一个工作表中信息,就相当于物理内存中存储的数据,点击工作表名,进入工作表,就能获得到数据位置。

这个例子,容易理解吧。然后,再对照上面的专业性内容看下,是不是容易理解了?

现在对虚拟内存和物理内存,是不是有了比较清楚的认识了。

但是,这还不是我们操作系统对内存管理的最优办法,因为,上面讲的方法,还存在容易产生内存碎片 和 内存交换效率不高的问题。

当连续启动多个进程时,会在内存条上分配连续的内存空间块,但是,一旦中间某个进程停了,释放内存空间,就会出现内存块不连续,出现内存碎片。

图解虚拟内存、物理内存、swap 分区的工作与管理_单片机_04

 

此时,如果启动一个新的进程,如果申请的内存空间大于剩余内存空间碎片的大小,就无法申请到内存空间而报错,但是,内存的实际总剩余空间可能又是大于申请的内存空间的。

举个例子,就像你有一个工作表,你开始写东西时,从第一行开始往下写,连续行,密密麻麻的写了很多。结果,你发现其中有些信息是无效的,不用了,你就把整行信息删除,但是没有删除行,这样,这个工作表,就出现了零碎的空行。现在,你又想利用空行,往里面写数据,但是你要写的数据是多行,行数大于零碎的空行。

你怎么办呢?

你是不是想到了,先剪切有数据的行到黏贴板,然后从空行位置开始黏贴,这样,是不是就可以把空行整理到一起了?

其实,我们计算机内存管理,也有类似的办法。

图解虚拟内存、物理内存、swap 分区的工作与管理_虚拟内存_05

 

在磁盘上虚拟一块空间,叫 swap 分区,然后,把内存中一整段空间,剪切到 swap 分区,然后,再还原回内存,这样,就移动了原来的内存空间位置,把空闲的内存空间整理到了一起。这个,是不是很容易理解了。

理解是容易了,但是,这个办法真的很好吗?

swap 分区,是由磁盘虚拟而来的,它的速度远远慢于内存速度,而一个进程,它的内存空间一般都是几百兆,如果,一次拷贝一个或几个进程的内存资源到 swap 分区,然后再还原到内存,这个时间势必会很长,用户就会明显感觉卡顿,甚至操作无响应。

这又该这么办呢?

如果是你,你会不会想,能不能一次不拷贝那么多、那么大,每次拷贝小点,分多次拷贝?

计算机也是这么想的,所以,就出现了一个内存分页管理。把整个虚拟内存和物理内存空间切成固定大小的页片,Linux 中,默认这个页片是 4K。若一个进程需要 256M 的内存空间,就把这个空间大小除以 4K,就得到了它的页片数,就分成这么多页。虚拟内存中,建立一个页表,记录页信息,需要的时候就去物理内存中获取,物理内存也不需要全部都存放,也可以在用的时候,内存再去其他设备上获取,因为每次都只获取几 K,量少,速度也会很快。

这个,我们怎么理解呢?

依然用 Excel 工作表举例,在一个表格中存了很多数据,我们可以根据某列的值进行分组,相同的为一组,那么,你要找某个数据时,是不是看下它的值,然后,直接找它那一组的数据,再从一组数据中找到你想要的数据,是不是要快很多。

但是,这个分组管理简单吗?

可能,想像中简单,但是实际工程中还是很复杂的。所以,这个页管理还是很复杂的。感兴趣的同学,可以自己再去学习研究。

好了,对于今天讲的虚拟内存、物理内存、swap 分区知识掌握了吗?