代码之家  ›  专栏  ›  技术社区  ›  Shimrod

不应该直接调用垃圾收集器的原因

  •  12
  • Shimrod  · 技术社区  · 14 年前

    我目前正在为我的公司写一篇论文,关于如何避免直接从代码中调用垃圾收集器(例如,在处理COM对象时)。

    我知道这是一种不好的做法,应该只在极少数情况下考虑,但我似乎找不到一种方法来解释为什么应该避免这种做法。我不想依赖“通用比你聪明”的原则(即使这是事实)。

    那么你能告诉我一些线索吗,为什么你认为应该避免直接给垃圾收集器打电话?(性能影响?)或者,如果您有关于这个特定主题的链接,它们将非常有用。

    事先谢谢!

    编辑:到目前为止,你提供的所有问题都非常有用。因为我不能验证每个人(或者我能吗?)我该怎么办?创建社区维基?

    4 回复  |  直到 14 年前
        1
  •  2
  •   Thomas Pornin    14 年前

    通常的性能参数是这样运行的:

    世代GC很快,因为它们依赖于启发式的,即许多分配的对象都是短期存在的(只要对象是“活的”,只要它是可到达的;GC的要点是检测“死的”对象并回收它们的内存)。这意味着对象可以聚集在一个特殊的区域(“年轻一代”);GC在该区域满时运行,并清除活动对象,将它们(“物理”)移动到旧一代。在大多数世代GC中,这个操作意味着一个暂停(“停止世界”),这是可以容忍的,因为它很短(年轻一代的规模有限)。在年轻一代的收集过程中,世界被暂停的事实允许有效地处理年轻对象(即,在年轻对象字段中读取或写入引用只是内存访问,不需要考虑来自GC线程或增量标记&扫描的并发访问)。

    一个年轻一代,如我上面所描述的,有一个集合运行,是有效的,因为当年轻一代被收集时,其中的大多数对象已经死了,所以他们不需要额外的费用。年轻一代的最佳规模是在最坏情况(所有年轻对象都是活的,这意味着最大的暂停时间)和平均效率(当年轻一代更大时,更多的对象在收集之前有时间死亡,这降低了GC的平均成本)之间进行权衡。

    手动运行GC类似于缩短年轻一代。这意味着更多的年轻物体将被提升到老一代,从而增加年轻一代的收集成本(必须清除更多的物体) 收集旧代的成本(要处理的旧对象较多)。

        2
  •  4
  •   Daniel Earwicker    14 年前

    主要原因是,一个程序在GC中花费的时间超过了执行完整收集所需的时间,它将比需要的时间慢。

    考虑到这是一个更容易得到更好的表现的情况,对我来说似乎是一个无脑的人!

    铌。在处理COM对象时,直接调用GC不太可能解决您的问题。如果COM对象挂起,那么它们具有非零的引用计数,并且任何额外的GC调用都不会解决这个问题。

        3
  •  1
  •   Josip Medved    14 年前

    它具有性能影响,因为需要停止所有线程才能执行收集。在那之后,它需要确定使用什么,不使用什么等等……

    所有这些都需要时间,只有当垃圾收集器确定好处大于坏处时,它才会工作。

    当您自己调用GC时,您很可能过于频繁地调用它,这将增加在GC中花费的时间,并减少在程序中花费的时间。

        4
  •  1
  •   Hans Olsson    14 年前

    如果您需要调用GarbageCollector以确保COM对象被释放,这可能是一个很好的迹象,表明您的开发人员没有调用 Dispose 和/或不使用 using 他们应该什么时候。所以有一个论点可能是它只是隐藏了错误的代码,而改为修复错误的代码会更好。