记忆管理理念
本文关键字:管理理 记忆 | 更新日期: 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();
,但它不起作用。。。
-
不要把你的游戏逻辑放在UI类中。
-
使用多媒体定时器和调度器返回到主线程进行渲染。根据我的经验,5mSec的周期运行良好。(降低会浪费CPU时间(。
-
使用Input的调度程序优先级,这样定时器就不会阻塞UI并阻止它处理用户事件。
-
在计时器事件中,如果上一次更新尚未完成,则立即返回而不执行任何操作(您可以使用System.Threading.Interlocked.CompareAndExchange作为一种廉价的同步方法(。
-
为了让游戏运行得更快,请尝试重用对象并更改它们的状态,或者传递短期免疫表,这样GC就不会延迟您的程序。
-
在适用的情况下使用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内置了内存探查器(可能更易于使用(。
我看到的持有引用的常见情况是通过事件订阅。如果您订阅了任何活动,则必须确保取消订阅才能发布对象。请参阅为什么以及如何避免事件处理程序内存泄漏?了解更多详细信息。这看起来不像你的问题。