You need to enable JavaScript to run this app. Unity运行时Update中如何按需更新List避免内存膨胀卡顿?
优惠活动
大模型
产品
解决方案
定价
更多

Unity运行时Update中如何按需更新List避免内存膨胀卡顿?

方案合理性判断

重新实例化List的方案本身完全成立

你遇到的卡顿根源是:每帧调用AddRange时没有清空原有数据,List会无限制累积历史每一帧抓取的所有LineRenderer坐标点,内存占用、后续遍历成本会随运行时间线性增长,最终触发卡顿。
你想到的「每次Update前重新实例化List」的逻辑,本质是让lineRendererPositions始终只存储当前帧的LineRenderer世界坐标点集合,没有冗余历史数据,从根源解决了List膨胀的问题。

  • 这个方案的GC开销极低:Vector3是值类型,重新实例化List的内存分配成本远低于无限制累积数据带来的性能损耗,正常项目运行中完全可以用,不需要为了微量GC刻意规避
  • 如果你本来的需求就是每帧获取最新的LineRenderer点集,这个方案已经完全满足要求,不需要额外写复杂的变化判断逻辑

什么时候需要加「内容不一致才更新」的判断

如果你的需求是仅当LineRenderer的点集发生实际变化时,才刷新List缓存,不需要每帧都拿最新数据,那才适合加对比逻辑,平白写逐点对比反而会增加不必要的CPU开销。
这类场景下的对比逻辑不需要写得太复杂,按优先级判断就行:

  • 第一步先对比长度:新拿到的点数组长度和现有List的Count不相等,直接判定点集发生了变化,直接重新赋值List即可,这一步判断的成本几乎可以忽略
  • 长度一致的情况下再做逐点校验:注意Vector3是浮点数,对比时要加极小的精度容差(比如0.0001),避免浮点计算精度误差导致的误判;只要任意一个点和List中对应位置的坐标差超过容差,就判定内容变化,重新赋值即可
  • 所有点都校验完成、没有发现差异的话,直接跳过更新逻辑就行

可以参考的实现代码:

private void Update()
{
    Vector3[] currentWorldPoints = GetLinePointsInWorldSpace();
    // 长度不一致直接判定点集变化
    if (currentWorldPoints.Length != lineRendererPositions.Count)
    {
        lineRendererPositions = new List<Vector3>(currentWorldPoints);
        return;
    }
    // 长度一致逐点校验变化
    bool isPointSetChanged = false;
    for (int i = 0; i < currentWorldPoints.Length; i++)
    {
        // 加入精度容差避免浮点误差
        if (Vector3.Distance(currentWorldPoints[i], lineRendererPositions[i]) > 0.0001f)
        {
            isPointSetChanged = true;
            break;
        }
    }
    if (isPointSetChanged)
    {
        lineRendererPositions = new List<Vector3>(currentWorldPoints);
    }
}

额外注意点

  • 不要为了“减少GC”刻意用Clear()清空List再AddRange:这种写法和重新实例化List的效果差不多,但Clear()不会自动收缩List的原有容量,如果你的LineRenderer点数量波动很大(比如之前存过1000个点,后来只有3个点),这种写法反而会长期占用不必要的内存
  • 如果业务逻辑就是每帧都要用到最新的LineRenderer点集,完全不需要做逐点对比,直接每帧重新赋值List即可,多余的对比逻辑反而会平白增加CPU占用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 13:45:05