长时间内存测试:增长斜率、变点检测与伪泄漏排除
内存曲线向上并不一定是泄漏,结束时回落也不一定安全。资源缓存、延迟回收、场景切换、采样噪声和真正的生命周期缺陷可能产生相似曲线。本文用分阶段斜率、变点和恢复能力建立更可靠的判定方法。
一、峰值和首尾差为什么不够
只比较开始与结束内存会遗漏中间危险峰值,也会把合理缓存误判为泄漏。一次长时间测试至少应区分预热、稳态操作、压力阶段、恢复等待和二次循环。
真正值得警惕的信号包括:相同操作循环后的基线逐轮抬升、停止操作后长时间无法回落、增长速率在特定事件后改变,以及内存增长同时伴随对象或资源类别持续增加。
二、先建立可比较的采样序列
每个样本至少包含单调时间、内存口径、测试阶段、循环编号、场景身份和重大事件。采样间隔应固定或明确记录;若时间间隔不等,不能直接按样本序号计算斜率。
内存口径也必须固定。进程物理内存、PSS、Native Heap、图形资源和引擎统计并不是同一个指标,不能拼成一条曲线。
三、分阶段估计增长斜率
对稳态区间拟合:
text
memory(t) = intercept + slope × t + noise
斜率比首尾差更能抵抗短时抖动,但普通最小二乘容易被尖峰拉偏。可以采用稳健回归或对多个局部斜率取中位数。报告必须给出窗口、样本数和不确定区间。
预热阶段通常允许正斜率;恢复阶段期待负斜率或回到稳定平台;重复循环的稳态平台不应持续上移。不同阶段不能用同一个阈值。
四、用变点定位"从哪里开始不正常"
变点检测寻找均值或斜率发生结构性变化的位置。检测到变点后,将其与加载、画质切换、角色生成、地图传送和网络重连等事件关联。
变点只是候选线索,不是根因。温控、后台任务和采样口径变化也能制造变点。只有与业务事件和资源证据互相印证,才能升级为缺陷结论。
五、设计恢复能力测试
压力结束后进入固定恢复窗口,停止输入、等待必要清理,并在受控条件下触发项目允许的释放机制。记录:
- 压力前稳定基线;
- 压力峰值;
- 恢复窗口最低值;
- 恢复比例与恢复耗时;
- 下一循环开始时的新基线。
text
recovery_ratio = (peak - recovered) / (peak - baseline)
该比例只能用于同口径、同场景比较。当峰值与基线过近时,比例会不稳定,应同时设置绝对差值条件。
六、如何排除常见伪泄漏
- 有界缓存:前几轮增长后进入平台,容量与策略一致;
- 延迟回收:在明确生命周期或等待窗口后下降;
- 资源预取:增长与后续内容加载对应,且有预算;
- 采样噪声:工具开销或系统统计更新导致短时跳动;
- 场景不一致:路线、角色或随机内容在各轮不同;
- 温度与系统压力:后台行为改变内存压缩或回收表现。
排除伪泄漏不等于忽略增长。即使是有界缓存,如果上限超出设备预算,仍然是性能问题,只是修复方向不同。
七、从趋势下钻到资源类别
趋势告警后,比较变点前后的 memreport、对象统计或资源清单。优先寻找数量与体积同时增长、生命周期与操作一致、恢复后仍保留的类别。差分时要按稳定资源身份聚合,避免动态地址和临时名称制造噪声。
八、自动门禁的建议结构
综合判定可以包含:稳态斜率、循环基线抬升、恢复比例、峰值预算和证据完整率。任何一项异常先生成候选,再根据重复实验确认。不要为了得到"零告警"而不断放宽阈值。
结语
内存泄漏测试不是盯着一条向上的线。把阶段、斜率、变点、恢复能力和资源差分串起来,才能区分合理增长、预算失控与真正的生命周期缺陷。