You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Block、Stack与Scratch分配器有何差异?各自优势及适用场景是什么?

三种核心内存分配器:差异、优势与适用场景

Mike Acton提到的这三种分配器,是引擎开发中经过验证的高效内存管理工具,它们的核心差异、优势和适用场景如下:

Stack Allocator(栈分配器)

  • 核心逻辑:模拟系统栈的「后进先出(LIFO)」行为,分配时仅需移动栈顶指针,释放时必须从最后分配的对象开始倒序释放,或者一次性清空整个分配器的内存块。可基于自定义内存池实现,不一定依赖线程的系统栈。
  • 优势:分配/释放操作几乎零开销;天然保证内存对齐;完全不会产生内存碎片。
  • 适用场景:生命周期严格嵌套的对象,比如函数内的临时变量、渲染管线中嵌套阶段的临时缓存、某一帧内创建且帧末销毁的资源。

Block Allocator(块分配器)

  • 核心逻辑:预先将大块内存划分为固定大小的内存块,按块的大小维护不同的空闲链表。分配时直接从对应大小的空闲链表中取出一块;释放时将块放回对应链表即可。和通用arena分配器的核心区别是:arena支持任意大小的拆分,而block分配器只处理固定尺寸的块。
  • 优势:分配/释放速度极快(仅链表操作);内存碎片可控(固定大小块不会产生细碎的无法利用的碎片);适合批量管理同类型对象。
  • 适用场景:大量同类型对象的频繁创建销毁,比如游戏中的实体组件、粒子系统的粒子实例、网络数据包对象。通常会维护多个不同尺寸的块池(如8B、16B、32B、64B),覆盖引擎中常用的对象大小。

Scratch Allocator(临时分配器)

  • 核心逻辑:属于特殊的栈式分配器,专门用于单次生命周期的临时内存。分配时同样移动指针,释放时不需要逐个倒序释放,直接将指针重置到初始位置即可一次性清空所有分配的内存。
  • 优势:比普通栈分配器更灵活,无需严格遵循LIFO释放顺序;分配速度同样极致;内存使用完即可一次性回收,无需跟踪单个对象。
  • 适用场景:一帧内的临时计算数据(如AI路径规划的临时节点数组)、渲染中的临时顶点/索引缓存、序列化/反序列化的临时缓冲区。

为什么这三种分配器就能覆盖绝大多数引擎开发场景?

引擎开发的内存需求有极强的规律性,这三种分配器刚好命中了核心场景:

  1. 临时内存需求占比极高:引擎中大量内存是单次帧内或单次调用的临时数据,Stack和Scratch分配器可以用极致的性能处理这类需求,完全替代低效的系统malloc。
  2. 同类型对象频繁操作:游戏实体、组件、粒子等都是高频创建销毁的同类型对象,Block分配器完美解决这类场景的碎片问题和性能开销。
  3. 简化内存管理复杂度:过多的分配器类型会增加代码维护成本,这三种分配器的组合已经能覆盖90%以上的性能敏感场景,剩下的极少数随机分配场景直接用系统默认分配器即可,不需要额外造轮子。

内容的提问来源于stack exchange,提问作者doliphin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 22:01:00