Skip to content

Linux的存储管理

Buddy内存管理算法

  • Buddy算法是经典的内存管理算法,也是实际在Linux中运行的一种内存管理算法
  • 算法基于计算机处理二进制的优势具有极高的效率
  • 算法主要是为了解决内存外碎片的问题
    • 页内碎片: 内部碎片是已经被分配出去(能明确指出属于哪个进程)的内存空间大于请求所需的内存空间,不能被利用的内存空间就是内部碎片。
    • 页外碎片: 外部碎片是指还没有分配出去(不属于任何进程),但是由于太小而无法分配给申请内存空间的新进程的内存空闲块
  • Buddy算法的目的就是努力让内存分配与相邻内存合并能快速进行
  • Buddy内存分配原则
    • 向上取整为2的幂大小1,例如
      1. 70k -> 128k
      2. 129k -> 256k
      3. 666k -> 1024k
  • Buddy伙伴系统介绍
    • "伙伴" 指的是内存的 "伙伴"
    • 一片连续内存的 "伙伴" 是相邻的另一片大小一样的连续内存
  • Buddy伙伴系统逻辑图解

    • 创建一系列空闲块链表,每一种都是2的幂
      Buddy伙伴系统逻辑图解
    • 根据下图,假设存储空间有1M大小,假设要分配100k内存
      Buddy伙伴系统逻辑图解
      1. 100k向上取2的幂=128k
      2. 查询是否有128k空闲内存块?
      3. 没有!查询是否有256k空闲内存块?
      4. 没有!查询是否有512k空闲内存块?
      5. 没有!查询是否有1M空闲内存块?
      6. 有,摘下1M空闲内存块,分配出去
      7. 拆下512k放在512k的空闲链表,其余的分配出去
      8. 拆下256k放在256k的空闲链表,其余的分配出去
      9. 拆下128k放在128k的空闲链表,其余的分配出去
      10. 分配完毕
    • 回收刚才分配的内存
      1. 判断刚才分配的内存伙伴在空闲链表上吗?
      2. 在!移除伙伴,合并为256k空闲内存,判断
      3. 在!移除伙伴,合并为512k空闲内存,判断
      4. 在!移除伙伴,合并为1M空闲内存
      5. 插入1M空闲链表,回收完成
  • Buddy内存管理算法是将内存外碎片的问题转换成了内存内碎片问题,但是也大大提升了整体性能,因为内存外碎片要比内存内碎片要大。

Linux交换空间

  • 交换空间(Swap)是磁盘的一个分区
  • Linux物理内存满时,会把一些内存交换至Swap空间
  • Swap空间是初始化系统时配置的

在Linux里查看swap

  • 查看系统Swap空间
    [root@jartins elastic_notes]# top
    top - 16:29:24 up 4 days, 15:26,  1 user,  load average: 0.09, 0.06, 0.05
    Tasks: 102 total,   1 running,  99 sleeping,   2 stopped,   0 zombie
    %Cpu(s):  0.5 us,  0.2 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem :  3688724 total,  1409184 free,   555956 used,  1723584 buff/cache
    KiB Swap:  1049596 total,  1049596 free,        0 used.  2826512 avail Mem 
    
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND  
    
  • swap存储在磁盘,效率较低,不建议过多使用

Swap交换空间有什么用呢

  • 冷启动内存依赖:对于一些大型的应用程序,在启动的过程中会使用大量的内存,但是这些内存只是在启动的时候用一下,后续在运行中很少再使用到这个内存,因此有个这个交换空间,系统就可以将不常用的信息交换存放到磁盘里面去,从而释放更多的物理内存,提供给系统使用。
  • 系统睡眠依赖:当Linux系统需要睡眠的时候,它就需要把系统里所有内存数据都保存到swap空间里面去的,等下次启动的时候就会重新从swap获取数据,这样就提升了系统的启动速度
  • 大进程空间依赖:有些进程需要很多的内存空间,但是物理内存是不够使用的,因此需要把进程使用到的这些内存暂时保存到swap磁盘空间中去,使得大的进程也能够运行起来

Swap空间与虚拟内存的差异

Swap空间 虚拟内存
Swap存在于磁盘 虚拟内存存在于磁盘
Swap空间与主从发生置换 虚拟内存与主存发生置换
Swap空间是操作系统概念 虚拟内存是进程概念
Swap空间解决系统物理内存不足问题 虚拟内存解决进程物理内存不足问题

  1. 向上取整到2的幂,指的是将一个数向上取整到最近的2的幂次方。

    例如,将7向上取整到2的幂次方,结果为8,因为2的3次方等于8,而2的2次方等于4,所以向上取整到最近的2的幂次方是将7四舍五入到8。

    对于任何一个正整数n,都可以将它转换为一个二进制数。将二进制数从右往左数,遇到0就跳过,遇到1时就将前一个数变成1并停止继续向右数,这时候剩余的数就是转换后二进制数长度。例如,n=7的二进制为111,从右往左数,遇到0跳过,遇到1时就将前一个数变成1并停止继续向右数,所以7的二进制数为1000000,长度为7。

    根据上述方法,我们可以将任何正整数n转换为一个长度为k的二进制数,其中k为n的二进制长度。然后将这个二进制数从右往左数,遇到第一个1时停止,将前一个数变为1并输出,输出的数就是向上取整到最近的2的幂次方。

    例如,n=10的二进制为1010,长度为4。从右往左数,第一个1在第三位,所以将第四位变为1并输出,输出的数为1000,即2的4次方。

    以下是Python代码实现:

    def ceil_pow2(n):
    k = 0
    while n:
        n = n >> 1
        k += 1
    return 1 << (k - 1)
    
    print(ceil_pow2(7)) # 输出8
    print(ceil_pow2(10)) # 输出16