2013-11-28 43 views
1

我很难理解与内存中的对象有关的一些概念,如果有人能让我走上正确的轨道,我将不胜感激。我意识到管理记忆有多重要,而且我担心我会采用糟糕的编程习惯。内存中的对象和一般的内存管理

在我的游戏循环我用lambda表达式的格式如下,从我的游戏删除对象:

ObjectsMan.lstExplosionParticles.RemoveAll(particle => particle.TTL <= 0); 

这些对象通常被实例化内部列表中添加方法,例如:

ObjectsMan.EnemyShots.Add(new EnemShot(current.SpritePosition + position.Key, 
Logic_ReturnValue.Angle_TarPlayer(current), position.Value)); 

据我了解,该列表正在存储对象的内存位置。所以当我从列表中删除它时,对象仍然存在于内存中。那是对的吗?

如果确实如此,即使我没有绘制它们,这些坐在内存中的物体是否会导致游戏滞后(例如,成千上万的单个抛射物体)?我是否需要手动将每个对象分配给null?

此外,如果我没有对我的游戏的绘制方法施加帧速率上限,我是否正确认为由于人眼无法看到帧而导致我失去了大量性能?

另一个问题是,如果我停止使用调试器并且正在播放声音,我的声音驱动程序就会锁定。我认为调用我的音效Stop方法会阻止这种情况发生。调试器在停止时绕过XNA的卸载内容方法吗?这里发生了什么?最后,如果我包括额外的使用陈述,我没有技术上需要,这是否影响我的记忆?例如,我的大多数类都包含一些他们实际上并不需要的使用语句。是否有一个性能相关的理由来清除这个问题,还是仅仅是一个好的编程习惯?

如果有人能给我一些帮助,或者指向正确的方向,我将不胜感激。

谢谢。

+0

所以你有一个包含对象的列表。当对象从列表中删除时,您不确定在GC启动之前对象是否会长时间保留在内存中,这是您的担忧吗? – ZZZ

+0

这是我的担心之一,是的。 GC直到节目结束才开始播放,这是否正确?仅仅因为我已经从列表中删除了这些对象,这不应该让GC有理由将我的对象从内存中删除?我说错了吗? – BeepBeep

回答

3

据我了解,该列表正在存储对象的内存位置。所以当我从列表中删除它时,对象仍然存在于内存中。那是对的吗?

是。你只是删除对象的引用。

如果确实如此,即使我没有绘制它们,那么坐在内存中的这些对象中的很多是否会导致游戏滞后(例如,数千个单个的抛射物体)?

直接?但是,当GC最后开始时,它们会导致滞后。仅仅因为GC有更多的对象需要照顾。我在Xbox360上遇到了同样的问题,它没有代代相关的GC。

我是否需要手动将每个对象分配给null?

这只是删除参考。与从列表中删除它相同。

最后,如果我包含额外的使用陈述,我没有技术上需要,是影响我的记忆?例如,我的大部分类都包含一些他们实际上并不需要的使用语句。是否有一个性能相关的理由来清除这个问题,还是仅仅是一个好的编程习惯?

这里应该没有问题。

GC直到程序结束才会启动,这是正确的吗?

错误。 GC可以随时运行。通常,如果应用程序决定内存不足并且操作系统无法提供任何操作,它将运行GC。

仅仅因为我已经从列表中删除对象,那不应该让GC理由从内存中删除我的对象?

如果此列表仅包含唯一引用,则GC可以自由删除该对象。但是,如果GC实际上在那个时候运行,那么它就没有关系。

另外,通常在编写游戏时,应该限制创建的对象的数量。简单地说,因为运行GC会产生很多不可预测的滞后。使用结构或重用现有的实例。在粒子系统的情况下,最好的方法是让每个粒子和场都有结构来表示粒子是否活跃。去除粒子时,只需将该字段设置为false即可。添加新粒子时,您会首先找到未激活的粒子并设置适当的字段并将其激活。

+0

这非常有帮助,谢谢。我一定会实现你的提示重用对象。 – BeepBeep

+0

您也可以选择使用GC.Collect()手动调用垃圾回收:http://stackoverflow.com/questions/1149197/gc-collect –