我怎样才能找出造成垃圾的原因?

时间:2013-12-05 23:58:06

标签: c# mono garbage-collection unity3d

这是一个非常基于学习的问题,而不是技术问题。

我正在Unity中制作游戏。游戏涉及许多相当复杂,高对象数的进程,因此,我产生了大量的垃圾。每个制作使用托管代码的游戏的人都知道,垃圾收集峰值是一个巨大的口号。我也试图瞄准移动设备,所以这种痛苦被放大了。

我的目标很简单:跟踪生成最多垃圾和池的过程并重用所涉及的对象,以减少垃圾收集器的负载。我已经处理了所有明显的类,但我的GC问题仍然存在。如果有人能在这里提供更多的智慧,请带上它。

我在研究中无法追踪的是测量GC负载和跟踪代码本身问题点的好方法。我可以从Unity和诊断类中获取有关内存池大小的指标(虽然我不知道这些数字的真正意义)并且我可以显示自开始以来发生的GC集合的总数,但是我调试这个问题的知识在那里结束了。

我知道必须有更好的方法来解决这个问题。任何人都可以指出我可以帮助我在这里的正确的工具或框架类(或库?)?我已经看到一些调试器程序(sgen?),它是Mono的一部分,但我找不到下载或更不用说如何将它连接到Unity游戏的指南。

非常感谢任何帮助。感谢。

2 个答案:

答案 0 :(得分:14)

对于C#和Unity3D,Unity3D中内置的探查器是您可以使用的最佳工具。您应该能够使用Unity Profiler。特别是CPU Profiler

enter image description here

我突出了最重要的专栏 - GC Alloc - 在逐帧的基础上,显示已分配用于垃圾回收的内存。这里游戏的目的是使该列尽可能接近零。

我建议花几个小时在那里玩游戏,暂停游戏并挖掘代码中GC Alloc显示数字的区域。

最后,我强烈建议您查看Unity的开发人员之一的内容调试 this 视频教程,并正确使用Unity Editor Profiler。

答案 1 :(得分:1)

警告:一切都归结为细节:一般原则很好,但你是对的 - 真正的数据是正确的。不幸的是,很难获得Unity:我见过reports that DotTrace works for some aspects of Unity games but that most of Unity looks like a black box to it

一个有用的经验法则是寻找语句。这是一个经验法则,而不是100%的科学原理(结构是用创建的,但它们会在堆栈中......主要是...)但它是可能导致碎片化的一个很好的领先指标。如果你“新”某事,如果只是消失(超出范围,被解除引用等),它将最终进入垃圾收集器。此外,如果您新建了一批项目并取消引用其中的一些项目,那么您还会对堆进行分段,这会使收集器出现问题,因为收集器会尝试对内存进行碎片整理。

这就是为什么这个空间中的大多数建议都是使用池,就像你已经在做的那样。

以下是一些通用链接,可能有助于解决Unity中的内存管理问题:

http://www.gamasutra.com/blogs/WendelinReich/20131109/203841/C_Memory_Management_for_Unity_Developers_part_1_of_3.php

http://andrewfray.wordpress.com/2013/02/04/reducing-memory-usage-in-unity-c-and-netmono/