3) 条件
· 两个块具有相同的大小
· 它们的物理地址是连续的
· 页块大小相同
4、如何分配 4M 以上内存?
1) 为何限制大块内存分配
· 分配的内存越大, 失败的可能性越大
· 大块内存使用场景少
2) 内核中获取 4M 以上大内存的方法
· 修改 MAX_ORDER, 重新编译内核
· 内核启动选型传递"mem="参数, 如"mem=80M,预留部分内存;然后通过
· request_mem_region 和 ioremap_nocache 将预留的内存映射到模块中。需要修改内核启动参数, 无需重新编译内核. 但这种方法不支持 x86 架构, 只支持 ARM, PowerPC 等非x86架构。
· 在start_kernel中mem_init 函数之前调用 alloc_boot_mem 函数预分配大块内存, 需要重新编译内核。
· vmalloc 函数,内核代码使用它来分配在虚拟内存中连续但在物理内存中不一定连续的内存。
5、伙伴系统—反碎片机制
1) 不可移动页
· 这些页在内存中有固定的位置,不能够移动,也不可回收。
· 内核代码段,数据段,内核 kmalloc() 出来的内存,内核线程占用的内存等。
2) 可回收页
· 这些页不能移动,但可以删除。内核在回收页占据了太多的内存时或者内存短缺时进行页面回收。
3) 可移动页
· 这些页可以任意移动,用户空间应用程序使用的页都属于该类别。它们是通过页表映射的。
· 当它们移动到新的位置,页表项也会相应的更新
6、slab 算法—基本原理
1) 基本概念
· Linux 所使用的slab分配器的基础是Jeff Bonwick 为 SunOS 操作系统首次引入的一种算法。
· 它的基本思想是将内核中经常使用的对象放到高速缓存中,并且由系统保持为初始的可利用状态。比如进程描述符,内核中会频繁对此数据进行申请和释放。
2) 内部碎片
· 已经被分配出去的的内存空间大于请求所需的内存空间。
3) 基本目标
· 减少伙伴算法在分配小块连续内存时所产生的内部碎片。
· 将频繁使用的对象缓存起来,减少分配、初始化和释放对象的时间开销。
· 通过着色技术调整对象以更好的使用硬件高速缓存。
7、slab 分配器的结构
· 由于对象是从 slab 中分配和释放的,因此单个 slab 可以在 slab 列表之间进行移动。
· slabs_empty 列表中的 slab 是进行回收(reaping)的主要备选对象。
· slab 还支持通用对象的初始化,从而避免了为同一目而对一个对象重复进行初始化。
8、slab 高速缓存