在循环中使用GC.Collect?

22

我在使用反编译器 Reflector 中发现了这段代码,它来自于 System.Web.ISAPIRuntime。

public void DoGCCollect()
{
    for (int i = 10; i > 0; i--)
    {
        GC.Collect();
    }
}

有人能对此发表评论吗?为什么要在循环中执行GC.Collect()?为什么是10次而不是3、5或20次?分析表明它未在.NET框架内使用,但是它是公共的,所以我猜想IIS可能会调用它...

编辑:

仅供澄清:我从未调用过GC.Collect,并且我没有使用它的意图。我知道在大多数情况下(如果不是所有情况),这是一个坏主意。问题是为什么.NET框架要这样做。感谢您所有的回答。

8个回答

14

是的,这很糟糕。首先,你根本不应该需要这样做。但是,如果你真的想尽可能强制进行垃圾回收,并等待其完成,你应该使用:

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
// Collect anything that's just been finalized
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

但这确实不是一个好主意。


@Brann:大对象是“收集”的,但LOH从未被“压缩”。这有很大的区别 :) - Jon Skeet
我在while循环中使用以下语句...但它不起作用(我遇到了OutOfMemoryException) GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); - Praveen Kumar
@PraveenKumar:那么也许你正在积累无法收集的对象? - Jon Skeet
现在我正在while循环中使用GC.Collect(),那么我该如何解决OutOfMemoryException? - Praveen Kumar
2
@PraveenKumar:调用 GC.Collect 并不是解决 OutOfMemoryException 的正确方法,很可能你只是在保留不该保留的引用。使用分析器找出原因。 - Jon Skeet
显示剩余5条评论

8

看起来真的很糟糕 :)


哈哈,这也是我的最初想法,我希望有人可以证明我错了 :P - Diadistis
被 System.Web 毁掉了,我认为这是框架中最糟糕的命名空间之一,还有办公室工具栏。 - Chris S
System.Web团队与.NET框架核心团队的合作非常糟糕。 - Patrick Peters

5
我认为你不可能得到比“微软的一位程序员相当无知,显然,在提交代码之前没有其他人注意他的代码”的更好解释。;)
虽然看起来很可怕。
但对于你不理解的错误,这是一个相当常见的响应。由于某种原因,你正在尝试调用GC,并且以某种方式,调用它似乎不能解决你的问题(也许真正的问题只是你应该等待终结器线程或其他东西),所以天真的解决方案显然是“嗯,我会继续调用它”。
类似于反复按“打印”直到打印出文档。
也许你应该将其提交到thedailywtf.com。

2

我非常喜欢该方法的Mono实现:

public void DoGCCollect ()
{
  // Do nothing.
}

也许开发人员本意是要写类似的内容,这只是一个拼写错误。

2
这种问题应该向微软反馈吗?在Connect网站上发布这个问题有用吗?

1

看起来像是一个有末日情结的人写的,暗示着他们将在10秒计时器结束世界...


0

这不是一个好主意,因为你真的应该相信垃圾回收器在没有从你的代码中特别调用的情况下完成其工作。

99.9%的时间,你不需要从你的代码中调用GC。


完全同意,这就是为什么我无法弄清楚这段代码在 .net 框架内部在做什么。 - Diadistis
哇 - 我没有看到你提到它的那一行!天啊! - Andrew Hare

0

首先,调用GC.Collect()并不是一个好主意。多次调用它几乎没有什么效果。

然而,有时你会看到这样的模式:先调用Collect(),然后调用WaitForPendingFinalizers(),最后再次调用Collect()。这样做的想法是确保具有终结器的实例也被回收,因为它们将在第一次垃圾回收中幸存下来。但请记住,这将导致应用程序延迟,并且应该非常少需要使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接