1. 先搞清楚这次内核更新到底动了哪块“蛋糕”如果你关注 Linux 内核开发,最近应该会注意到一个消息:Linux 内核 7.2 版本对Slab 内存分配器的核心结构freelist进行了重构,引入了“延迟构建”机制。官方数据显示,在某些场景下,单次内存分配的速度最高能提升 70%。这个数字听起来很夸张,但它不是凭空而来的。要理解这个优化的价值,得先明白 Slab 在 Linux 里是干什么的。简单说,内核里频繁创建和销毁的小对象(比如进程描述符task_struct、文件描述符file、网络套接字socket),如果每次都直接向更底层的伙伴系统(Buddy System)申请整页内存,效率太低,碎片也多。Slab 就是为解决这个问题而生的“对象缓存池”,它预先从伙伴系统申请一批连续内存页(一个slab),然后切成固定大小的小块(object)进行管理。freelist就是这个缓存池里,用来快速追踪哪些object是空闲可用的链表。在 7.2 之前的内核中,一个slab被创建时,它的freelist会立即被初始化——也就是把所有可用的object链接成一个链表。这听起来很合理,但问题在于,很多slab在它的生命周期内,可能根本不会被完全使用。想象一下,一个只为偶尔创建的大文件准备的inode缓存slab,大部分时间可能只被用了一两个object,但初始化时却把成百上千个object的链表都建好了。这个“预构建”工作,在slab创建时就产生了固定的、无法避免的开销。7.2 的“延迟构建freelist”优化,核心思想就是“按需构建”。它不再在slab创建时一股脑儿建好整个空闲链表,而是推迟到真正需要分配object的时候。这带来了几个立竿见影的好处:加速冷启动:创建slab(尤其是大型slab)的速度更快,因为省去了初始化整个freelist的循环操作。减少内存访问:在分配路径上,减少了对于可能永远不会被访问的object的指针解引用,对 CPU 缓存更友好。提升分配速度:对于部分使用的slab,分配逻辑可能更简单直接。这个优化主要影响的是频繁创建和销毁特定类型内核对象的场景,比如高并发的网络服务、虚拟化环境、或者某些文件系统操作。对于普通桌面用户,感知可能不强;但对于云服务器、数据库、高频交易系统,这可能是实实在在的性能提升。下面,我们就拆开看看这个改动具体是怎么做的,以及在实际环境中如何观察和验证它的效果。1.1 Slab 与 Freelist 的基本工作模式要理解“延迟构建”好在哪里,得先看看原来是怎么做的。在经典的 SLUB 分配器(当前内核默认)实现中,一个kmem_cache结构管理一类对象(比如task_struct)。每个 CPU 有一个本地的kmem_cache_cpu结构,其中page指针指向当前活跃的slab,freelist指向这个slab中第一个空闲object。传统的freelist是一个嵌入在每个空闲object内部的单链表。在slab初始化时,内核会遍历这个slab中的所有object,把它们的地址按顺序串联起来。假设一个slab包含 N 个object,初始化后的freelist就像这样:freelist - obj1 - obj2 - obj3 - ... - objN - NULL当需要分配时,操作非常简单:从freelist取出第一个object的地址(obj1)。将freelist更新为obj1内部存储的下一个指针(即obj2的地址)。返回obj1给调用者。释放时,操作相反:将待释放object内部的下一个指针指向当前freelist。将freelist更新为这个待释放object的地址。这种方式在slab被高度使用时效率很高。但问题就在于“初始化”