记忆管理理念

本文关键字:管理理 记忆 | 更新日期: 2023-09-27 18:09:32

我正在用SharpDX用C#编写一个游戏。。。所以,为了绘制一个框架,目前我使用的是计时器,间隔设置为1;但这对游戏来说太慢了,所以我想要更快的。。。首先,如果我为游戏使用另一个线程(为Window本身使用另一线程(,并使用"[while(InGame(]"语句,这很快,但GC永远不会释放一个对象,内存使用率会越来越高。。。

如果我使用"RenderLoop"函数中内置的SharpDX,它也很快,但GC仍然什么都不做。。。

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

这是我的第一个真正的游戏,有很多功能,所以,如果你们中的任何人有任何想法,我该如何修复它,或者我应该使用什么,我将不胜感激。。。窗口窗体生命周期中一定有类似的东西

void FormLife
{
     WndProc();
     HandleEvents();
     etc...
}

(这只是一个很难的例子…(

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

记忆管理理念

  1. 不要把你的游戏逻辑放在UI类中。

  2. 使用多媒体定时器和调度器返回到主线程进行渲染。根据我的经验,5mSec的周期运行良好。(降低会浪费CPU时间(。

  3. 使用Input的调度程序优先级,这样定时器就不会阻塞UI并阻止它处理用户事件。

  4. 在计时器事件中,如果上一次更新尚未完成,则立即返回而不执行任何操作(您可以使用System.Threading.Interlocked.CompareAndExchange作为一种廉价的同步方法(。

  5. 为了让游戏运行得更快,请尝试重用对象并更改它们的状态,或者传递短期免疫表,这样GC就不会延迟您的程序。

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

如果GC.Collect没有释放内存,则存在内存泄漏。使用您选择的内存评测工具来发现泄漏(PerfView、Windbg、.NET内存评测器、YourKit……(

除此之外,最好的分配就是根本不分配。如果重用对象并将未使用的对象保留在池中,则可以几乎完全消除GC。即使你远离第二代收集,因为它会阻止你的游戏数百毫秒,你也需要密切关注第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

您通常不必担心内存管理。如果您确定不保留引用,那么垃圾收集器应该根据内存压力自动执行它的操作。

你可以自己使用GC.Collect强制它,但你需要绝对确定你真的需要。大多数时候这是不需要的。查看此线程以获取更多信息和需要考虑的要点:在C#中强制垃圾回收的最佳实践

由于对象没有被收集,您必须在某个地方保存对它们的引用。

你没有发布太多代码,所以很难说你在哪里有引用。

在过去,我曾使用windbg来查找内存问题的根本原因。VS2013内置了内存探查器(可能更易于使用(。

我看到的持有引用的常见情况是通过事件订阅。如果您订阅了任何活动,则必须确保取消订阅才能发布对象。请参阅为什么以及如何避免事件处理程序内存泄漏?了解更多详细信息。这看起来不像你的问题。