如果我不收集垃圾,为什么服务器垃圾收集会更快?

时间:2015-04-04 22:39:17

标签: c# performance garbage-collection clrprofiler

我正在编写数据结构,如果我在<gcServer enabled="true" />文件中设置app.config,程序会在200毫秒内添加500,000个项目。如果我设置<gcServer enabled="false" />则需要300毫秒。也就是说,将此标志设置为false会使其持续时间延长50%,如Stopwatch所示。

我想知道为什么这是因为我没有做任何垃圾收集。我知道它有时会自动完成,但在使用CLRProfiler进行分析后,我可以确认正在发生0个集合:

enter image description here

有谁知道为什么会这样?如果垃圾收集器甚至没有运行,那为什么服务器垃圾收集器会这么快?这是我检查速度差异的代码:

Stopwatch sw = Stopwatch.StartNew();

foreach (string s in items)
{
    dataStructure.Add(s, s + "a");
}

sw.Stop();

1 个答案:

答案 0 :(得分:0)

这里我需要介绍五件事。

首先要了解的是,此标志不会打开或关闭垃圾收集器,而只是确定其使用的模式。这两个示例都启用了垃圾回收。只有第一个(较慢的)示例使用了服务器垃圾回收。

第二个理解仅仅是因为没有执行任何收集,这并不意味着GC从未停止过检查是否需要运行收集。

这是excerpt from the gcServer docs的第三个:

  

对于单处理器计算机,默认的工作站垃圾回收应该是最快的选择。

第四,在上述情况下理解“单个处理器”确实是指处理器,而不是内核。

将所有这些放在一起,问题的行为与文档完全匹配。向前走;没什么可看的。

第五,最后,是了解游戏中的值以及服务器负载与桌面负载有何不同。在服务器系统中,最重要的是稳定性。即使在性能上也是如此。如果系统始终崩溃,则性能无关紧要。此外,服务器更有可能运行进程寿命较长的工作负载,甚至一次甚至数月或数年,而无需重新启动。因此,服务器管理员可能会牺牲一些性能来使GC的运行频率更高一些并运行更完整的检查,这可能包括内存压缩以回收地址空间,从而避免了OutOfMemoryExceptions问题,否则可能导致长期存在的问题.Net应用程序。