游戏内存碎片诊断:总量没超标,为什么仍然分配失败
可用内存总量看似充足,较大连续分配却失败,或者长时间运行后分配延迟不断上升,可能与碎片、尺寸类别、对齐和生命周期混杂有关。本文从分配器视角建立诊断方法。
一、外部碎片和内部碎片
外部碎片是空闲空间被切成无法满足大请求的小块;内部碎片是分配单元大于真实需求造成浪费。不同分配器和内存区域表现不同,不能只用一个碎片百分比解释全部问题。
二、需要采集的指标
- 申请大小与实际占用大小分布;
- 尺寸类别的使用率与空闲块;
- 大分配失败和延迟;
- 分配生命周期与线程;
- 峰值、保留量、提交量和可回收量;
- 场景阶段与资源类型。
三、生命周期混杂
长寿命对象和大量短寿命对象混在同一区域,会留下难以复用的空洞。按生命周期或资源类型隔离 Arena,可能比压缩单个对象更有效。但过多 Arena 也会增加保留和尾部浪费。
四、时间趋势
在重复场景循环中观察:总占用是否恢复、最大可用块是否持续下降、分配延迟是否抬升。若总量稳定但最大块下降,支持外部碎片候选;若实际请求小而占用持续偏大,检查内部碎片和对齐。
五、受控实验
- 固定分配序列,改变释放顺序;
- 分离长短生命周期对象;
- 调整尺寸类别或对齐策略;
- 对比不同场景切换周期;
- 在相同峰值总量下测试大块申请。
实验环境必须可重复,地址和线程调度随机性要记录。
六、常见误区
- 把缓存保留量全部称为碎片;
- 只看进程总内存,不看分配器区域;
- 通过频繁强制回收掩盖生命周期问题;
- 为解决一次大分配失败无限提高内存预算;
- 使用不同构建或分配器配置比较趋势。
七、验收
修复后比较最大连续可用块、分配失败率、P95/P99 分配延迟、内部浪费、峰值内存和场景恢复能力。优化碎片不能以显著增加总保留量为代价而不说明。
结语
内存是否健康不仅取决于用了多少,还取决于空间如何组织、对象活多久以及分配器能否复用空洞。总量、连续性和分配延迟必须联合分析。