为游戏和其他实时应用程序调整.NET4.5GC的常用方法?

为游戏和其他实时应用程序调整.NET4.5GC的常用方法?,.net,garbage-collection,.net-4.5,.net,Garbage Collection,.net 4.5,我正在用C#开发一个游戏引擎,遇到这样的情况:在执行一些内存密集型操作时,垃圾收集每多帧就会导致明显的口吃。在.NET中调整垃圾收集器以避免此类问题或为实时应用程序优化垃圾收集器的常用方法有哪些?从分析开始。找出是什么给你带来了麻烦,并找到一种摆脱它的方法。有一些调整,比如使用多线程GC,但这只对具有几个工作线程的服务器应用程序有很大帮助 您最好的办法是确保您释放的大部分内存仍在第0代—这些集合通常足够快,不会在60 FPS的应用程序中引入停顿 当然,就像C++或其他任何东西一样——限制你的分配

我正在用C#开发一个游戏引擎,遇到这样的情况:在执行一些内存密集型操作时,垃圾收集每多帧就会导致明显的口吃。在.NET中调整垃圾收集器以避免此类问题或为实时应用程序优化垃圾收集器的常用方法有哪些?

从分析开始。找出是什么给你带来了麻烦,并找到一种摆脱它的方法。有一些调整,比如使用多线程GC,但这只对具有几个工作线程的服务器应用程序有很大帮助

您最好的办法是确保您释放的大部分内存仍在第0代—这些集合通常足够快,不会在60 FPS的应用程序中引入停顿

当然,就像C++或其他任何东西一样——限制你的分配和释放。你可能正在做很多完全不必要的事情——同样,分析可以帮助你很容易地确定这些事情。如果你每隔几帧就收集一次,那你就大错特错了


当然,C++为您提供了一些重用内存的选项。然而,这并不是目前无法克服的。GC只处理堆分配(和集合)——堆栈仅用作根引用之一。因此,根据您的设计,例如,如果在方法中分配新类作为局部变量,那么用
struct
s替换这些类可能是非常值得的,这些类将倾向于在堆栈上分配。没有办法强制执行此行为(在不安全代码之外-在尝试此操作之前,您应该始终考虑10次:D),但CLR确实尝试将任何可以放在堆栈上的内容放在堆栈上:)

您注意到完整的GC或Gen1或Gen0?基于此,您可以应用多种策略来防止GC。例如,通过使用结构等避免堆分配。您需要测量和理解底层问题。正在发生的具体问题是每帧运行的体素映射到网格转换函数。我不期望这种情况在游戏引擎的实际使用中发生,但它在演示中用于水效果。我已经在它上面运行了探查器,并设法解决了它出现的主要问题,但没有看到比我已经完成的改进更多的改进。@LaylConway通常,您不会重新创建网格。这就是顶点缓冲区和类似缓冲区派上用场的地方——您可以根据需要预先分配任意数量的索引和顶点,并且只根据需要填充数据(那些是结构,您可以避免数百万次分配)——在渲染时,渲染尽可能多的实际数量,而不是整个顶点/索引缓冲区。事实上,VB/IBs早在实际的.NET游戏出现之前就已经出现了,这很好地说明了非托管代码也存在类似的性能问题:)谢谢,我将介绍如何为此重新使用数组和VBO。同时,经过一些优化后的扫描显示,现在大多数分配实际上是由多维数组acessor和。。。如果发生过多的分配,引擎中警告我的部分。