4

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

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

在此处输入图像描述

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

Stopwatch sw = Stopwatch.StartNew();

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

sw.Stop();
4

1 回答 1

0

这是我需要介绍的五件事。

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

其次是理解仅仅因为没有执行收集,并不意味着 GC 从未停止检查是否需要运行收集。

第三是文档的摘录gcServer

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

第四是理解上述上下文中的“单处理器”确实是指处理器,而不是内核。

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

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

于 2019-04-03T18:32:32.903 回答