我有许多运行相同进程的Windows 2008 R2 24核心服务器,但每个进程实例都有不同的数据集。通常,每个服务器上运行2-4个进程实例。这些进程是针对x64编译的,具有GUI,并使用Workstation GC。
每秒,进程将GC计数输出到本地磁盘上的日志文件。该日志也用于许多其他事情。偶尔,我发现其中一个进程暂停执行5秒或更长时间。我发现在这段时间内没有任何内容写入日志。每次发生这种情况时,它都会以Gen2 GC的数量增加1来结束。
这是一件罕见的事。这可能发生在所有进程中每10000个Gen2 GC一次。
每台机器都有足够的RAM来保存RAM中的所有进程。
今天早上我在其中一个进程中暂停了9秒,这次我捕获了受影响进程和整个计算机的性能计数器。当时正在运行的其他进程都没有受到影响。性能计数器的分析显示如下:
暂停前与暂停前比较:
任何人都可以确认此活动可归因于交换吗?鉴于机器有足够的内存,有没有修复这些暂停的建议?
更新#1(3/5/2012):
在今天的其中一个过程中经历了6.5秒的停顿。 .NET Clr内存性能计数器显示LOH的大小没有变化,但是Gen 2堆的大小和所有堆的大小以及总提交字节数减少了700 Mb。保留字节总数减少了250 Mb。因此,似乎Gen2中的大量垃圾在这个特定的GC上被回收。
更新#2(3/6/2012):
今天在其中一个进程中经历了7秒的停顿。以下内容: Gen 2堆大小(.NET CLR内存)900 Mb 所有堆中的字节数(.NET CLR内存)增加900 Mb Num Total Commited Bytes(.NET CLR内存)800 Mb Num Total Reserved Bytes(.NET CLR Memory)540 Mb 虚拟字节(处理)550 Mb 工作集(流程)800 Mb 工作集 - 私人(流程) 页面文件字节数(处理)800 Mb 私有字节(进程)800 Mb
LOH保持不变
答案 0 :(得分:3)
看起来您的应用程序的行为使得大对象堆中的许多段可能在同一GC 2周期内变为“死”(请参阅this link in msdn)。当GC 2中的LOH段在GC 2之后死亡时,它将返回到OS,当您同时返回大量的时,这可能很昂贵。
您的应用程序可能不属于CLR GC模式调整范围。如果您的应用程序重复分配大型对象(如大型数组),您可能会看到通过自己汇集和重新使用它们而不是依赖GC来获得更可预测的GC行为。
答案 1 :(得分:2)
看起来真正的Gen2 GC在几个演出的过程中需要几秒钟。
那么为什么有些Gen2 GC需要5秒钟而其他人几乎没有时间?因为我启用了并发/后台Gc,并且看起来好像当并发GC完成时,Gen2 GC计数器会递增。我认为这是误导。
禁用Concurrent GC后,Gen2 GC计数大幅下降,每个Gen2 GC需要几秒钟。