内存管理理念?

时间:2014-06-20 21:41:56

标签: c# memory

我用SharpDX用C#编写游戏...... 因此,对于绘制一个帧,目前我使用的是Timer,间隔设置为1; 但这对游戏来说太慢了,所以我想要更快的东西...... 首先,如果我使用另一个线程进行游戏(另一个用于Window本身),我使用" [while(InGame)]"声明,它很快,但GC永远不会释放单个对象,并且内存使用率只会上升......

如果我使用内置的SharpDX" RenderLoop"功能,它也很快,但GC仍然没有做任何事情......

我试图覆盖Window窗体" WndProc"功能,但游戏只刷新自己然后我像疯子一样移动鼠标......

这是我的第一部真正的游戏,有很多功能, 所以,如果你们有任何想法,我将如何解决它,或者我应该使用什么,我将不胜感激...... Window Form生命周期中必须有一些像

一样的东西
void FormLife
{
     WndProc();
     HandleEvents();
     etc...
}

(这只是一个很难的例子......)

或者如何在while(InGame)状态结束时强制GC完成其工作? 我试过了GC.Collect();,但它不起作用......

4 个答案:

答案 0 :(得分:5)

  1. 不要将游戏逻辑放在UI类中。

  2. 使用multimedia timer和调度程序返回主线程进行渲染。根据我的经验,5毫秒的循环效果很好。 (较低会浪费CPU时间)。

  3. 使用Input的调度程序优先级,以便计时器不会阻止UI并阻止它处理用户事件。

  4. 在计时器事件中,如果先前的更新尚未完成,则立即返回而不做任何事情(您可以使用System.Threading.Interlocked.CompareAndExchange作为便宜的同步方法)。

  5. 为了让游戏运行得更快,请尝试重用对象并更改其状态或传递简短的不可变因素,以便GC不会延迟您的程序。

  6. 在适用的情况下使用IDisposable模式。

答案 1 :(得分:1)

如果GC.Collect没有释放内存,则会出现内存泄漏。使用您选择的内存分析工具来发现泄漏(PerfView,Windbg,.NET Memory Profiler,YourKit,....)

除此之外,最佳分配根本没有分配。如果您重用对象并将未使用的对象保留在池中,您几乎可以完全摆脱GC。即使你远离可以阻挡你的游戏数百毫秒的第二代收藏品,你也需要密切关注Gen 0/1收藏品,这也会导致明显的延迟。

请参阅http://social.msdn.microsoft.com/Forums/vstudio/en-US/74631e98-fd8b-4098-8306-8d1031e912a4/gc-still-pauses-whole-app-under-sustainedlowlatency-latencymode-despite-it-consumes-025gb-and?forum=clr

答案 2 :(得分:0)

您通常不必担心内存管理问题。如果你确定不要保留引用,那么垃圾收集器应该根据内存压力自动完成它。

你可以使用GC.Collect自己强制它,但你需要绝对确定你真的需要。大多数时候它不是必需的。请查看此主题以获取更多信息并指出要考虑的问题:Best Practice for Forcing Garbage Collection in C#

答案 3 :(得分:0)

由于没有收集对象,你必须在某处持有对它们的引用。

您没有发布太多代码,因此很难说您持有引用的位置。

过去我曾使用windbg来查找内存问题的根本原因。内置VS2013 has a memory profiler(可能更容易使用)。

我见过持有引用的常见情况是通过事件订阅。如果您已订阅任何事件,则必须确保取消订阅以释放该对象。有关详细信息,请参阅Why and How to avoid Event Handler memory leaks?。这看起来不像你的问题。