Unity GC 优化:面向初学者

引言        

        Unity项目里“卡顿/掉帧”中很大一部分原因来自 托管堆(Managed Heap)的短时间内大量分配导致频繁触发GC(垃圾回收)。本文从原理 → 检测 → 常见坑 → 实战策略 → 示例代码,逐步把每帧分配降到可接受的水平(理想情况每帧GC alloc≈0)。
        

简单概念回顾

  • GC Alloc:托管堆上新分配对象(new、某些API返回临时对象、字符串拼接、装箱等)。Unity Profiler中会显示每帧分配量(KB)。

  • 垃圾回收(GC):当分配累积到一定量,CLR/Mono/IL2CPP会停止世界并清理不可达对象,造成卡顿。

  • 目标:尽量把每帧的GC Alloc降到最低(理想:每帧0KB或 极低),把大多数分配移到初始化/加载阶段或后台(非渲染关键路径)。

如何分析问题

  1. Unity Profiler

    • 打开Profiler → CPU Usage → 看GC Alloc列(每帧分配)。

    • 点击具体帧 → Timeline → 找出“Which function allocated”。

  2. Deep Profiling

    • Deep Profiling会自己产生大量分配与开销,平时不要开,只有必要时短时间开启。

  3. Memory Profiler

    • 用于快照、查看堆上对象分布与大小。

  4. Runtime Allocation Callstacks

    • Profiler的“Record Allocations”或某些插件可以展示分配调用栈,帮助定位代码行。

  5. 目标指标

    • 将每帧GC Alloc控制在0–1KB;移动设备上尽量0KB。

常见会产生GC Alloc的场景

  • 每帧new(例如在Update()中频繁new对象、临时Vector3数组等)。

  • 字符串拼接("x:" + x会生成临时字符串)。

  • 使用string.FormatToString()每帧。

  • 使用LINQ(Where().Select()会分配枚举器、闭包等)。

  • foreach在某些IEnumerable上会产生分配(特别是非泛型集合、yield返回的枚举器、某些 Unity API)。

  • 装箱(把value-type当作object或传给需要object的API)。

  • 频繁Instantiate()/Destroy()(GameObject分配/释放代价高)。

    <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

☆平常心☆

若恰好帮到你,便是一场缘分

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值