.NET 4.0进程执行暂停几秒钟,与完整GC冲突,是否由交换文件活动引起?

.NET 4.0进程执行暂停几秒钟,与完整GC冲突,是否由交换文件活动引起?,.net,garbage-collection,performancecounter,swapfile,.net,Garbage Collection,Performancecounter,Swapfile,我有许多Windows 2008 R2 24核心服务器运行相同的进程,但进程的每个实例都有不同的数据集。通常在每台服务器上运行2-4个进程实例。这些进程是为x64编译的,具有GUI,并使用工作站GC 每秒钟,进程都会将GC计数输出到本地磁盘上的日志文件。日志还用于许多其他用途。偶尔,我会发现其中一个进程会暂停执行5秒或更长时间。我看到在这段时间内没有任何内容写入日志。每次发生这种情况,Gen2 GCs的数量都会增加1 这是一个罕见的事件。在所有进程中,这种情况可能每10000 Gen2 GCs发

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

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

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

每台机器都有足够的RAM,可以将所有进程保存在RAM中

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

暂停后与暂停前的比较:

  • 虚拟字节、页面文件字节、虚拟字节、工作集和进程专用工作集的删除量大致相同-1Gb。为了让您了解进程的大小,专用字节从3.1 Gb降至2.1 Gb
  • 进程的句柄计数从8835减少到8705
  • 整个机器的可用字节增加了约1 Gb
  • 页面错误/秒未达到峰值
  • 暂停期间CPU使用稳定
有人能确认此活动可归因于交换吗?鉴于机器有足够的RAM,有没有关于修复这些暂停的建议

更新1(3/5/2012):

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

更新#2(3/6/2012):

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


LOH保持不变

看起来应用程序的行为是这样的:大型对象堆中的许多段可能在同一个GC 2周期内“死亡”(请参阅)。当LOH中的一个段在GC 2之后失效时,它将返回到操作系统,当您同时返回很多段时,这可能会很昂贵


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

一个真正的Gen2 GC在几个Gig大小的进程上花费几秒钟的时间

那么,为什么有些Gen2地面军事需要5秒,而有些则几乎不需要时间呢?因为我启用了并发/后台Gc,并且似乎在并发Gc完成时,Gen2 Gc计数器递增。我认为这是误导


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

您是否考虑过这一点:?发生这种情况时,您是否尝试查看.Net性能计数器?例如,查看LOH前后的大小可能会很有趣。在我寻找这个问题的答案时,我曾经遇到过Marc Gravell的帖子,如果发现LOH是罪魁祸首,那么Marc帖子中的一些建议可以用来缓解这个问题。嗯,我想现在你需要弄清楚为什么一个垃圾收集会释放这么多垃圾。恐怕我们帮不了你。但是内存分析器可能会。Svick和antlersoft的评论指出LOH垃圾收集可能是延迟的一个原因。我没有考虑过这个。我已经设置了捕获必要的性能计数器,一旦得到一些结果,我将更新此线程。