Unity:在我的函数中分配内存的是啥?
Posted
技术标签:
【中文标题】Unity:在我的函数中分配内存的是啥?【英文标题】:Unity: What's allocating memory in my function?Unity:在我的函数中分配内存的是什么? 【发布时间】:2018-09-14 01:07:44 【问题描述】:我对内存和优化比较陌生。我的任务是优化现有项目,在查看 Unity 中的分析器时,我看到有一个函数产生了一堆东西供 GC 清理。
函数是这样的:
public bool AnyCanvasOpen()
for (int i = 0; i < canvasList.Count; i++)
if (canvasList[i].activeSelf && canvasList[i].name != "MainUICanvas")
return true;
return false;
canvasList 只是一个游戏对象列表。我的 282B 分配可能是什么原因?
【问题讨论】:
【参考方案1】:canvasList
变量是 List
的 GameObject
和 Unity 的 GameObject
派生自 UnityEngine.Object
,它具有您正在使用的 name
属性。
内存分配来自于:canvasList[i].name != "MainUICanvas"
这是因为Object.name
属性需要从本机端返回一个字符串,这意味着每次访问该属性时都会创建一个新字符串。这就是添加GameObject.CompareTag
函数的原因,以便在不分配内存的情况下比较对象名称。 GameObject.CompareTag
函数将在本机端比较对象名称,而无需在 C# 端创建或返回新字符串。这消除了内存分配。
不幸的是,他们网站和其他地方的大多数 Unity 代码示例都使用 Object.name
而不是 GameObject.CompareTag
函数,这导致更多人更频繁地使用 Object.name
属性。
这不应该分配内存:
List<GameObject> canvasList = new List<GameObject>();
public bool AnyCanvasOpen()
for (int i = 0; i < canvasList.Count; i++)
if (canvasList[i].activeSelf && canvasList[i].CompareTag("MainUICanvas"))
return true;
return false;
【讨论】:
我尝试了你的建议,但它给了我一个 6kb 的分配空间。似乎GameObject.CompareTag
调用了LogStringToConsole
,其中有一些分配但是,似乎内存分配确实来自canvasList[i].name != "MainUICanvas"
。即使提供的解决方案没有按预期工作,但从技术上讲,您确实回答了我的问题,所以这将是公认的答案。
我最终创建了一个新的List<string>
来包含画布名称列表,这样我就不必每帧调用几次canvasList[i].name
。这将分配减少到 0B。一个更好的方法来做到这一点将不胜感激
不确定你在说什么。 CompareTag
确实 不 分配内存,并且该函数中没有其他任何东西可以。内存分配是否减少并不重要。它根本不应该分配。请注意,如果您正在比较的标签不存在,您可能会在分析器中看到内存分配,因为 Unity 将 throw an error 并且内存分配是由于错误日志造成的。
如果不是这样,那么内存分配来自另一个地方。启用深度配置文件以找到它。最后,请注意,您应该不是从编辑器项目中调试构建/独立项目,因为有些分配发生在编辑器中而不是在构建中。
我并不是说GameObject.CompareTag
本身有一些分配,它是 something 随之而来的(这确实是一个错误),如果我用你不明白的方式表达了它。内存分配是错误日志,因为我试图比较的是 GameObject.name
而不是标签。尝试使用 GameObject.CompareTag
会产生错误,因为我试图找到的画布未标记。感谢您的帮助以上是关于Unity:在我的函数中分配内存的是啥?的主要内容,如果未能解决你的问题,请参考以下文章