我正在做一个关于 .Net CLR GC 的介绍性演示,并拥有所有不同的部分,但我想要一个具体的例子来说明试图强制收集是如何危险或有害的。我知道你可以过早地将事情强加给更高的世代,但是(据我所知)这只会减慢速度。
我正在尝试考虑强制 GC 可能真正具有破坏性的情况,而我一直在想出效率较低的解决方案。
我正在做一个关于 .Net CLR GC 的介绍性演示,并拥有所有不同的部分,但我想要一个具体的例子来说明试图强制收集是如何危险或有害的。我知道你可以过早地将事情强加给更高的世代,但是(据我所知)这只会减慢速度。
我正在尝试考虑强制 GC 可能真正具有破坏性的情况,而我一直在想出效率较低的解决方案。
这是一个有趣的演示。请注意,您应该运行在发布模式下编译的这个演示,否则它可能无法像宣传的那样工作。
版本 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#
中。
下面这个坏主意呢?“让我们在 ASP.NET 中的每个 HTTP 请求之后强制进行 GC,以清理肯定会成为孤立的请求状态!”
这是一个坏主意,因为并发 HTTP 请求会相互干扰。这会引入大量延迟峰值并破坏性能。所有这一切都从一个天真的“优化”开始。
这是我能想到的最糟糕的情况。