8

我正在做一个关于 .Net CLR GC 的介绍性演示,并拥有所有不同的部分,但我想要一个具体的例子来说明试图强制收集是如何危险或有害的。我知道你可以过早地将事情强加给更高的世代,但是(据我所知)这只会减慢速度。

我正在尝试考虑强制 GC 可能真正具有破坏性的情况,而我一直在想出效率较低的解决方案。

4

2 回答 2

4

这是一个有趣的演示。请注意,您应该运行在发布模式下编译的这个演示,否则它可能无法像宣传的那样工作。

版本 1:

private void Button_Click(object sender, EventArgs e)
{
    Timer timer = new Timer(Print, null, 0, 1000);
}

private void Print(Object o)
{
    if (textBox1.InvokeRequired)
    {
        Action<object> action = Print;
        textBox1.Invoke(action, o);
        return;
    }

    textBox1.Text = DateTime.Now.ToString();
}

版本 1 会愉快地将日期和时间每秒打印一次到文本框。

版本 2:

private void Button_Click(object sender, EventArgs e)
{
    Timer timer = new Timer(Print, null, 0, 1000);
}

private void Print(Object o)
{
    if (textBox1.InvokeRequired)
    {
        Action<object> action = Print;
        textBox1.Invoke(action, o);
        return;
    }

    textBox1.Text = DateTime.Now.ToString();

    GC.Collect(); // force a garbage collection
}

现在在版本 2 中,日期和时间将只打印一次,因为在声明之后,不再有对计时器对象的引用,因此计时器对象被收集。

这是一个相当人为的例子,但可能是一个很好的演示。

我必须感谢杰弗里·里希特(Jeffery Richter)——这是在他的优秀著作CLR via C#中。

于 2012-07-23T20:28:27.337 回答
1

下面这个坏主意呢?“让我们在 ASP.NET 中的每个 HTTP 请求之后强制进行 GC,以清理肯定会成为孤立的请求状态!”

这是一个坏主意,因为并发 HTTP 请求会相互干扰。这会引入大量延迟峰值并破坏性能。所有这一切都从一个天真的“优化”开始。

这是我能想到的最糟糕的情况。

于 2012-07-23T19:59:09.763 回答