合聚咖

合聚咖

Linux内存管理——伙伴系统之避免碎片

admin

分页与分段是信息存储管理的基本方式。页是物理存储单位,分页用于解决内存碎片问题,而段则是逻辑存储单位,旨在满足程序共享需求。页大小固定由系统确定,段长度则由程序或编译器根据信息性质划分。分页作业地址空间为一维,而分段则为二维。

内部碎片与外部碎片是分页与分段存储管理中常见的问题。在页式虚拟存储系统中,作业大小与物理块大小不匹配导致的浪费空间称为内碎片。相反,段式虚拟存储系统中,各段之间不连续导致的内存浪费称为外碎片。

在内存管理中,“内零头”和“外零头”指的是在不同分区管理方式中,由于存储空间分配与释放的不连续性,导致的无法利用的小块内存空间。固定分区和可变分区分配中,内碎片分别体现在分配给程序的内存空间可能大于其实际需求,导致剩余空间无法使用;而外碎片则出现在内存分配后,为满足不同大小需求,导致的连续内存空间断裂。

伙伴系统分配内存大小要求为2的幂指数页,这同样导致内部碎片。伙伴系统基本原理为使用双链表管理内存,此方案在近几年表现良好,但对Linux内存管理存在长期问题:系统运行时间越长,物理内存碎片越多。这一问题在下图中直观体现。在左图中,无法映射大于一页的内存区;在右图中,连续分配较大内存时,碎片问题更为严重。

值得注意的是,碎片问题不仅仅局限于内核内存管理,现代CPU提供使用巨型页功能,可以显著提高内存使用效率,降低地址转换后备缓冲器的访问频率。然而,分配巨型页需要连续的空闲物理内存。

Linux内核采用两类方法解决内存碎片问题:依据可移动性组织页和虚拟可移动内存域。依据可移动性组织页方法在内核2.6.24期间引入,通过将页划分为可移动性不同的类别并分别管理,以减少碎片。相反,虚拟可移动内存域方法要求管理员显式激活,将物理内存划分为可移动和不可移动两部分,自动防止不可移动页向可移动内存域引入碎片。

在依据可移动性组织页方法中,内核定义了枚举常量表示不同迁移类型,如MIGRATE_CMA,用于解决特定硬件需求,如GPU、Camera、HDMI等设备的内存需求。内核通过反碎片技术,如将页划分成可移动性不同的列表,避免内碎片问题。此外,内核提供了一系列函数和数据结构来管理不同迁移类型的内存分配。

虚拟可移动内存域方法通过将内存分为两个域,一个用于可移动分配,一个用于不可移动分配,自动防止不可移动页向可移动内存域引入碎片。这要求管理员根据预期的内存使用场景来配置域的大小,以在两个竞争的内存域之间进行内存分配。

总结而言,Linux内核通过伙伴系统、依据可移动性组织页和虚拟可移动内存域等方法有效地避免了内存碎片问题,从而优化了内存使用效率和系统性能。