
1) 【一句话结论】在Unity项目中,通过Unity Profiler发现协程未正确清理导致对象持续引用,通过检查引用链并调用Destroy()方法解决了内存泄漏问题。
2) 【原理/概念讲解】内存泄漏的核心是对象被持续持有引用,导致Unity的垃圾回收器(GC)无法回收该对象。可以类比成“房间里的垃圾”:如果有人一直拿着垃圾(持续引用对象),保洁员(GC)就收不到垃圾,房间垃圾越堆越多。在Unity中,当对象被脚本、协程、静态变量等持续引用时,即使对象不再使用,GC也无法回收其内存,最终导致内存占用持续增长。
3) 【对比与适用场景】
| 工具 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| Unity Profiler | 实时性能分析工具 | 可监控对象分配率、内存使用趋势、CPU/GPU占用 | 定位实时内存增长、性能瓶颈 | 需要持续运行,实时数据 |
| Memory Profiler | 内存快照分析工具 | 可导出内存快照,查看对象引用链、内存占用对象 | 分析内存泄漏、内存占用大的对象 | 需要暂停游戏,分析静态内存 |
4) 【示例】
伪代码示例(最小可运行场景):
using UnityEngine;
public class MemoryLeakExample : MonoBehaviour
{
void Start()
{
StartCoroutine(LeakCoroutine());
}
IEnumerator LeakCoroutine()
{
while (true) // 协程无限循环,未正确清理
{
Debug.Log("Running coroutine...");
yield return new WaitForSeconds(1f);
}
}
}
问题点:协程LeakCoroutine无限循环,未在完成时释放资源,导致协程相关的对象被持续引用,内存无法回收。
5) 【面试口播版答案】
“面试官您好,我分享一个Unity项目中遇到的内存泄漏问题。当时项目里有个协程在处理数据时,没有正确清理,导致一个对象被持续引用。首先我用Unity Profiler监控,发现内存使用率持续上升,没有下降趋势。然后切换到Memory Profiler,导出内存快照,发现那个协程相关的对象没有被回收。接着检查代码,发现协程在完成时没有调用Destroy()销毁对象,导致对象引用链一直存在。解决方法是修改协程,在最后一步调用Destroy(this.gameObject)或者Destroy(targetObject),确保对象在协程完成后被销毁,这样GC就能回收内存,内存使用率恢复正常。”
6) 【追问清单】
7) 【常见坑/雷区】