3

我有许多运行相同进程的 Windows 2008 R2 24 核心服务器,但进程的每个实例都有不同的数据集。通常在每台服务器上运行 2-4 个进程实例。这些进程针对 x64 编译,具有 GUI,并使用 Workstation GC。

每一秒,该进程都会将 GC 计数输出到本地磁盘上的日志文件中。日志也用于许多其他事情。偶尔,我发现其中一个进程会暂停执行 5 秒或更长时间。我看到在这段时间内没有任何内容写入日志。每次发生这种情况时,Gen2 GC 的数量都会增加 1。

这是一个罕见的事件。这可能在所有进程中每 10000 次 Gen2 GC 发生一次。

每台机器都有足够多的 RAM 来将所有进程保存在 RAM 中。

今天早上,我在其中一个进程中暂停了 9 秒,这次我捕获了受影响进程和整个机器的性能计数器。当时运行的其他进程都没有受到影响。性能计数器分析显示以下内容:

暂停后与暂停前的比较:

  • 进程的虚拟字节、页面文件字节、虚拟字节、工作集和私有工作集减少了大约相同的数量 - 1Gb。为了让您了解进程的大小,私有字节从 3.1 Gb 下降到 2.1 Gb。
  • 进程的句柄计数从 8835 减少到 8705
  • 整个机器的可用字节增加了大约 1 Gb
  • 页面错误/秒没有达到峰值
  • 暂停期间 CPU 使用率稳定

谁能确认此活动可归因于交换?鉴于机器有足够多的 RAM,是否有任何修复这些暂停的建议?

更新 #1(2012 年 3 月 5 日):

今天在其中一个过程中经历了 6.5 秒的暂停。.NET Clr 内存性能计数器显示 LOH 的大小没有改变,但 Gen 2 堆的大小和所有堆的大小以及提交的总字节数下降了 700 Mb。总保留字节减少了 250 Mb。因此,似乎在这个特定的 GC 上回收了 Gen2 中的很多垃圾。

更新 #2(2012 年 3 月 6 日):

今天在其中一个过程中经历了 7 秒的停顿。以下内容已删除:第 2 代堆大小(.NET CLR 内存)增加了 900 Mb 所有堆中的 Num 字节数(.NET CLR 内存)减少了 900 Mb 提交的总字节数(.NET CLR 内存)增加了 800 Mb 保留的字节总数(.NET CLR 内存)。 NET CLR 内存)540 Mb 虚拟字节(进程)550 Mb 工作集(进程)800 Mb 工作集 - 私有(进程)页面文件字节(进程)800 Mb 私有字节(进程)800 Mb

LOH保持不变

4

2 回答 2

3

看起来您的应用程序的行为使得大型对象堆中的许多段可能在同一个 GC 2 周期内变得“死”(请参阅​​ msdn 中的此链接)。当 LOH 中的一个段在 GC 2 后死亡时,它会返回到操作系统,当您同时返回大量它们时,这可能会很昂贵。

您的应用程序可能会超出 CLR GC 模式调整的范围。如果您的应用程序重复分配大对象(例如大数组),您可能会通过自己池化和重用它们而不是依赖 GC 来查看是否获得了更可预测的 GC 行为。

于 2012-02-28T17:45:13.453 回答
2

看来,真正的 Gen2 GC 需要几秒钟的时间来处理几个 gigs 大小的过程。

那么为什么有些 Gen2 GC 需要 5 秒,而另一些几乎不需要时间呢?因为我启用了并发/后台 Gc,并且它看起来好像在并发 GC 完成时,Gen2 GC 计数器增加了。我认为这是误导。

禁用并发 GC 后,Gen2 GC 计数会大幅下降,并且每次 Gen2 GC 需要几秒钟。

于 2012-04-26T19:51:41.967 回答