Linux的存储管理(Buddy算法和Swap空间)

Buddy内存管理算法(伙伴系统)

Buddy算法是经典的内存管理算法,也是实际在Linux里面运行的一种内存管理算法。它是基于计算机处理二进制具有极高的效率设计的算法。主要是为了解决内存外碎片问题。

了解buddy算法之前需要先了解两个简单的概念,即页内碎片和页外碎片。

页内碎片

内部碎片是已经被分配出去的(能明确指出属于哪个进程)内存空间大于请求所需的内存空间,不能被利用的空间就是内部碎片。

页外碎片

外部碎片是指还没分配出去(不属于任何进程),但是由于大小无法分配给申请内存空间的新进程的内存空闲块。

在这里插入图片描述
上面是我用excel画的一张示意图
假设左边的颜色区域整块是一个页面,橘色的是一个进程实现需要申请的内存,但是操作系统在进行段页式存储管理的时候只能把这一整页分配给进程。在这个页面里,进程没有利用到的灰色区域就是页内碎片。
假设右边每一个橘色的块是一个页面,在这个内存里,每一个页面都被分配出去了,但是图中灰色的这块小内存由于不满足一页大小导致无法利用。所以它是页外碎片。

Buddy内存管理算法

努力的让内存分配与相邻内存的合并能够快速进行,也依赖于计算机在处理二进制的速度这一特性。

内存分配的原则:
内存分配的时候,默认每一块内存向上取整为2的幂的大小。比如一个进程需要申请70k的内存,buddy算法会向上取整2的幂次方,即128k,类似的例子如5k取8k,13k取16k,17k取32k等。

伙伴系统
伙伴系统是buddy算法的核心概念。“伙伴”指的是一片内存的“伙伴”,即一片连续内存中相邻的另外一片大小一样的连续内存。比如在内存有两块大小一样的空闲区域,空闲区1和空闲区2是连续的,那么它们互为“伙伴”。

算法的具体流程
首先创建一系列的空闲块链表,每一个链表的大小都是2的幂次方大小。
在这里插入图片描述
我用Excel画的图,橘色表示双向链表的指针,蓝色表示节点。

举个例子:
假设在存储空间里有1MB的大小,Buddy内存管理初始化空闲块链表1KB,2KB,4KB等等这些空闲块链表都是没有节点的,只有1MB的空闲块链表有一个节点,它的大小是1MB。
那么如何使用buddy算法去分配100k的内存呢?

  1. 首先把100k向上取2的幂次方为128k,
  2. 接着查询空闲块链表内是否有128k的空闲内存块,此时是没有的;
  3. 没有继续查询是否存在256k的空闲内存块,依旧不存在
  4. 继续查询512k的空闲内存块,没有;
  5. 继续查询是否存在1024KB即1MB的空闲内存块,发现有,就从1MB的空闲块链表里面把1MB的空闲内存块摘下来分配出去。这样1MB的空闲链表将没有节点。
  6. 接下来从1MB里面拆下512k放在512k的空闲块链表里,其余的分配出去,此时判断512k是否已经满足最小的需求。
  7. 上述步骤512k并没有满足最小需求,继续把剩下的512k拆成256k和256k,其中256k放到空闲块链表,剩下的256k分配出去继续判断是否满足100k的最小需求。
  8. 上述当然不满足最小需求,继续拆分成两个128k,其中一个128k放在空闲块链表,再把剩下的128k分配出去。
  9. 再次判断128k是不是满足最小需求,此时已经达到步骤1的需求,表示分配完毕。

分配过程如下图(依旧Excel画的图)
在这里插入图片描述
通过上述例子可以发现buddy算法处理空闲块内存都是以2的幂的大小,这是因为计算机处理2的幂时速度时极快的,因此buddy算法既有很高的效率。

回收内存的过程

  1. 首先判断刚才分配的内存的伙伴是否在空闲链表上。
  2. 发现存在的,此时移除伙伴,合并为256k的空闲内存,继续判断256k的伙伴是否在空闲块链表里
  3. 此时依旧存在,移除伙伴和合并为512k空闲内存,再次判断。
  4. 再次存在,合并为1M的空闲内存。接着判断1MB内存的伙伴是否在空闲块链表里面。
  5. 发现不存在,将1MB的空闲块内存插入到1MB的空闲块链表,此时完成了128k内存的回收。

回收完成之后,如上图左半边部分,算法内的空闲块链表1k-512k的空闲块链表都是无节点的。只有1M有一个节点同时也是前面回收的内存。

Buddy算法主要解决内存外碎片问题,其实是将内存外碎片问题转移成内存内碎片问题。上述例子实际需要100k内存但分配了128k内存,多出来的28k就是内存内碎片。

Linux交换空间

交换空间(swap)实际是磁盘的一个分区,在系统初始化时需要配置。当Linux物理内存满的时候,就会把一部分的物理内存交换到swap空间里面去,使得Linux物理内存有更多的空间去运行。
在Linux使用top命令可以查看swap空间的使用情况。

避免使用交换空间
虽然swap空间可以使得Linux物理内存置换到swap空间里,但是swap空间存储的地方在磁盘,磁盘的速度比Linux慢很多。如果频繁使用,就会让Linux系统运行变慢。

交换空间的作用

  1. 冷启动内存依赖。对一些大型应用程序,在启动的过程中需要使用大量的内存,这些内存很多时候只是启动的时候用一下。依靠交换空间,系统可以把不怎么使用的内存数据保存到交换空间里,从而释放更多的物理内存提供给系统使用。
  2. 系统睡眠依赖。当Linux系统需要睡眠的时候,会把系统里面所有内存数据都保存在交换空间里,等下一次系统启动的时候再把这些数据重新加载到内存里面,加快了系统的启动速度。
  3. 大进程空间依赖。有些进程需要很多的内存空间,但是物理内存不够使用,因此把进程需要使用到的内存暂时保存到交换空间里。

交换空间类似于虚拟内存,比较区别

  • 交换空间和虚拟内存都存在于磁盘
  • 工作原理都是与主存发生置换
  • 交换空间是Linux角度操作系统的概念,虚拟内存则是进程概念
  • 交换空间解决系统物理内存不足问题,而虚拟内存解决进程物理内存不足问题

猜你喜欢

转载自blog.csdn.net/wankcn/article/details/108370357