我用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();
,但它不起作用......
答案 0 :(得分:5)
不要将游戏逻辑放在UI类中。
使用multimedia timer和调度程序返回主线程进行渲染。根据我的经验,5毫秒的循环效果很好。 (较低会浪费CPU时间)。
使用Input的调度程序优先级,以便计时器不会阻止UI并阻止它处理用户事件。
在计时器事件中,如果先前的更新尚未完成,则立即返回而不做任何事情(您可以使用System.Threading.Interlocked.CompareAndExchange作为便宜的同步方法)。
为了让游戏运行得更快,请尝试重用对象并更改其状态或传递简短的不可变因素,以便GC不会延迟您的程序。
在适用的情况下使用IDisposable模式。
答案 1 :(得分:1)
如果GC.Collect没有释放内存,则会出现内存泄漏。使用您选择的内存分析工具来发现泄漏(PerfView,Windbg,.NET Memory Profiler,YourKit,....)
除此之外,最佳分配根本没有分配。如果您重用对象并将未使用的对象保留在池中,您几乎可以完全摆脱GC。即使你远离可以阻挡你的游戏数百毫秒的第二代收藏品,你也需要密切关注Gen 0/1收藏品,这也会导致明显的延迟。
答案 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?。这看起来不像你的问题。