为什么你的内存池写得不够快?来看 Linux SLUB 分配器教科书级的 O(1) 路径 很多程序员第一次看见void *p = kmalloc(64, GFP_KERNEL);这样的代码时,脑子里浮现出来的画面都很相似:内核收到一个“我要 64 字节”的请求,然后像一个经验丰富但仍然很忙的仓库管理员那样,在某个全局空闲空间里翻找一块大小刚好够用、最好还别太碎的内存,最后把地址递给调用者。这个画面不算完全错误,因为在最底层你终究要落回页面、落回物理内存、落回页分配器;但如果你拿着这个画面去理解现代 Linux 小对象分配的快路径,你会很快陷入一个解释不通的困境:如果每次kmalloc都真的在“找”空闲块,它怎么可能在高并发、高频率的小对象分配场景里,常常表现得像常数时间一样稳定?答案恰恰在于,kmalloc真正高明的地方不是“把查找写得更快”,而是在绝大多数高频小对象路径上,尽量把“查找”这件事从运行时消灭掉。当一次 64 字节请求进入 SLUB 的世界,它不再被当成“连续数轴上一个精确的 64”来处理,而是先被离散化成一个固定 size class,再被路由到一个预先建好的对象缓存池;如果该缓存池在当前 CPU 的本地 freelist 上正好有现货,那么这次分配的真实动作就会收缩成“从本地货架上摘下一个对象、改一下头指针、返回地址”,也就是说,它更接近“取对象”而不是“找内存”。这就是本文的主问题,也是我认为市面上大多数 slab/slub 文章没有真正讲透的地方:kmalloc 为什么能快到接近 O(1),不是因为内核突然掌握了某种神秘的全局搜索算法,而是因为它先把问题改写成了一个根本不需要全局搜索的问题。如果你把这个认知真正