如何提高垃圾收集性能?

时间:2008-10-04 12:00:22

标签: .net optimization compact-framework embedded garbage-collection

可以使用哪种优化模式来提高垃圾收集器的性能?

我的理由是我使用Compact Framework做了很多嵌入式软件。在慢速设备上垃圾收集可能会成为一个问题,我想减少垃圾收集器启动的次数,当它发生时,我希望它能更快地完成。我还可以看到使用垃圾收集器而不是垃圾收集器可以帮助改进任何.NET或Java应用程序,尤其是重型Web应用程序。

以下是我的一些想法,但我没有做任何基准测试。

  • 重用临时类/数组(记下分配计数)
  • 将活动对象的数量保持在最低(更快收集)
  • 尝试使用结构而不是类

6 个答案:

答案 0 :(得分:12)

关键是要了解CF GC如何用于分配。它是一个简单的标记 - 扫描,非代际GC,具有触发GC的特定算法,以及在收集后会导致压缩和/或投球的因素。在应用程序级别几乎没有什么可以控制GC(唯一可用的方法是Collect,它的使用非常有限,因为你无论如何都不能强制压缩。)

对象重用是一个好的开始,但简单地保持对象数量低可能是最好的工具之一,因为所有的根都必须为任何集合操作而行走。保持走路是一个好主意。如果压缩正在扼杀你,那么阻止段碎片会有所帮助。对象> 64k在这方面可能会有所帮助,因为它们获得了自己的段,并且与较小的对象区别对待。

要真正了解CF GC的工作原理,我建议您观看MSDN Webcast on CF memory management

答案 1 :(得分:3)

最重要的一个方面是最小化分配率。每当分配一个对象时,它就需要GC。当然,如果对象是 small shortlived ,它将在年轻一代中被钉(假设GC是世代的)。大型物体往往直接进入终身体育馆。但是完全避免收集甚至更好。

此外,如果你可以把东西放在堆叠上,你将对GC的压力降低很多。您可以尝试使用GC选项进行操作,但我认为您可以更好地使用分配探查器,因此您可以找到导致问题的位置。

应该注意的是标准库和框架的重量。你包装了几个对象,它会很快填满。请记住,每当GC堆上发生某些事情时,它通常会使用更多空间进行GC簿记。因此,单独分配的1000个指针比同一指针的数组/向量大得多,因为后者可以共享GC簿记。另一方面,后者可能会活得更久。

答案 2 :(得分:2)

一个重要的事实是尽可能缩短对象的生命周期。

答案 3 :(得分:2)

结构与类的问题是一个复杂的问题......例如,您可能很容易最终使用 lot 更多的堆栈空间。你肯定不想要可变的结构。但其他一点似乎是明智的,只要你没有弯曲设计变形以适应它。

[edit] 另一个常见问题是字符串连接;如果你在循环中进行连接,请使用StringBuilder,这将删除 lot 的中间字符串。可能是GC正在忙着收集所有废弃的字符串?

答案 4 :(得分:2)

另一种选择是使用GC.Collect()在应用程序的非高峰时间手动收集垃圾(假设这在CF中可用)。这可以减少应用程序中稍后清理所需的对象。

答案 5 :(得分:0)

我在.NET Rocks听到Rotor 2.0节目。如果你真的是硬核,你可以下载Rotor,调整源代码,并使用你自己的修改过的垃圾收集器。

无论如何,该播客在GC上有一些很棒的信息。我强烈建议听一听。