代码之家  ›  专栏  ›  技术社区  ›  Martin Liesén

如何提高垃圾收集性能?

  •  9
  • Martin Liesén  · 技术社区  · 16 年前

    什么样的优化模式可以用来提高垃圾收集器的性能?

    我问这个问题的原因是我使用紧凑的框架做了很多嵌入式软件。在速度较慢的设备上,垃圾收集可能会成为一个问题,我希望减少垃圾收集器启动的次数,当它启动时,我希望它完成得更快。我还可以看到,使用垃圾收集器来代替它可以帮助改进.NET或Java应用程序,尤其是重型Web应用程序。

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

    • 重用临时类/数组(减少分配计数)
    • 将活动对象的数量保持在最小(更快的集合)
    • 尝试使用结构而不是类
    6 回复  |  直到 16 年前
        1
  •  12
  •   ctacke    16 年前

    关键是了解CF GC如何处理分配。这是一个简单的标记和扫描,非世代GC,具有触发GC的特定算法,以及在收集后导致压缩和/或变桨的算法。在应用程序级别上,您几乎无法控制GC(唯一可用的方法是collect,它的使用非常有限,因为您无论如何都不能强制压缩)。

    对象重用是一个很好的开始,但是简单地保持对象计数低可能是最好的工具之一,因为任何收集操作都必须遍历所有根。保持短距离行走是个好主意。如果压缩会使您丧命,那么防止片段破碎将有所帮助。对象>64K在这方面很有用,因为它们有自己的段,并且与较小的对象的处理方式不同。

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

        2
  •  3
  •   I GIVE CRAP ANSWERS    16 年前

    最重要的一个方面是最小化分配率。无论何时分配对象,稍后都需要GC。当然,如果物体是 小的 短暂的 它将在年轻一代中被钉住(前提是GC是世代的)。大型物体往往直接进入终身竞技场。但是,完全不必收集就更好了。

    另外,如果你能把东西扔到堆栈上,你在GC上的压力会小得多。您可以尝试使用GC选项,但我认为您可以更好地使用手头的一个分配分析器,这样您就可以找到产生问题的地方。

    我们应该注意的是标准库和框架的重量。你把一些东西包起来,它会很快填满。记住,每当GC堆上有东西出现时,它通常会为GC簿记使用更多的空间。因此,单独分配的1000个指针远大于相同指针的数组/向量,因为后者可以共享GC簿记。另一方面,后者可能会活得更长。

        3
  •  2
  •   Marc Gravell    16 年前

    结构与类问题是一个复杂的问题…你可能很容易使用 许多 例如,更多的堆栈空间。你当然不想要可变的结构。但其他的观点似乎是合理的,只要你不弯曲设计的形状来适应它。

    [编辑] 另一个常见的方法是字符串连接;如果在循环中进行连接,请使用StringBuilder,它将删除 许多 中间字符串。可能是GC正忙着收集字符串中所有废弃的容器?

        4
  •  2
  •   Inisheer    16 年前

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

        5
  •  2
  •   VVS    16 年前

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

        6
  •  0
  •   Jason Z    16 年前

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

    无论如何,那个播客有一些关于GC的重要信息。我强烈建议你听听。