【发布时间】:2015-04-12 08:41:49
【问题描述】:
我们正在使用Unity3D 引擎开发一款游戏(它使用 Mono 作为用户代码 - 我们的代码是用 C# 编写的)。
场景是我们有一个暴露事件的类,大约有 250 个注册到该事件(游戏地图上的每个关卡对象都将自己注册到该事件):
// Every level registers itself (around 250 levels)
ScoresDataHelper.OnScoresUpdate += HandleOnScoresUpdate;
当销毁这个场景时,每个对象都会从事件中注销自己:
ScoresDataHelper.OnScoresUpdate -= HandleOnScoresUpdate;
当使用内置分析器时,我看到一个巨大的内存分配,深入挖掘表明这是由于未注册的代表。
我怀疑这是因为委托是不可变的,当将它们链接在一起时,会创建新实例?
这是 Unity 分析器的屏幕截图:
在处理大量事件订阅时,有什么办法可以避免这些内存分配?
【问题讨论】:
-
有问题吗? GC 将在需要时立即启动并收集垃圾。顺便说一句,您想注销订阅该事件的每个对象还是只有少数对象?
-
是的,这是一个问题,因为它分配了大约 3MB 并且还消耗时间。这使得从地图场景移动到实际游戏的体验需要更长的时间才能开始。
-
嗯,请回答我的第二个问题“您想注销订阅该事件的每个对象还是只有少数对象?” Benjamin Gruenbaum 也为您提供了一个很好的答案。
-
是的,都应该退订。当然,总是可以选择重新设计系统,以避免一开始就进行 250 次注册。我只是想从理论上了解如何处理许多正在注册的事件的问题,因为它似乎会产生如此高的内存分配。