为什么这段代码导致内存泄漏?

时间:2017-06-22 16:54:53

标签: c# unity3d

只有一个默认摄像头和一个GameObject。

为什么销毁游戏对象仍然在内存中?我试图手动调用GC,Resources.UnloadUnusedAssets和其他一些黑客没有成功。 我的游戏需要动态创建GameObjects ... ObjectPooling当然可以完成但是因为玩家将玩几个小时并且有很多不同的精灵我认为这仍然是个问题。

{{1}}

3 个答案:

答案 0 :(得分:1)

您的代码中存在三个问题:

1 。问题是gb.AddComponent<SpriteRenderer>();。在场景重新加载之前,添加SpriteRenderer似乎没有释放内存。 这是代码中的主要问题。

2 。从this.objects = new List<GameObject>();函数中删除Update。您已在Start函数中完成此操作。您只会创建更多不需要的列表。

该代码行应替换为this.objects.Clear();,因为在下一行向其添加更多对象之前,它将清除列表。

3 。由于性能问题,您应该永远致电Resources.Load中的Update。这就像每帧加载一个文件一样,这将影响游戏的性能。

  

ObjectPooling当然可以完成但是因为玩家将是   玩了几个小时,我认为这有很多不同的精灵   仍然会有问题。

不,不。对象池是解决此问题的方法,因此您不会在每个帧中添加新的SpriteRenderer

阅读this以获取解释,并阅读可轻松用于对象池的ArrayObjectPooling类。

答案 1 :(得分:0)

你的GameObject是COM对象吗?如果是,则通过将引用指针添加到列表来增加引用指针,但不要通过释放gb变量来释放引用计数器。

答案 2 :(得分:0)

您有内存泄漏并调用垃圾收集器的原因是没有做任何事情是因为您声明的方式

private List<GameObject> objects;

在实例化公共类Game:MonoBehavior时,您将此声明为全局变量。

当调用垃圾收集时,这最终会将List放入第2代对象池中,这些对象在不再使用该类之前不会被处理掉。

我确实看到了两个选项,你可以通过将对象放在允许内存被普通垃圾收集器释放的方法中来缩小对象的范围,因为它将成为该点的第1代或第0代对象。 / p>

或者您可以在列表上调用 TrimExcess(),这会将列表中任何已分配空间的内存减少到该列表中对象实际占用的内存量。

以下是有关C#的垃圾收集器和对象生成的一些有用链接:

https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals

http://www.dotnettricks.com/learn/netframework/net-garbage-collection-in-depth