我在Windows Server 2003 x64(2x Xeon 4核心触发器)上运行一个大型.net 4.0 x86应用程序,并且遇到了我的应用程序〜每天2-3次冻结30秒,然后恢复运行的问题像平常一样。该应用程序每周只重启一次,并消耗400-800 MB的内存,所以我假设这些冻结是垃圾收集。我只看到日志中的冻结,而不是现场,或者我会检查任务管理器以确认。
我试图弄清楚哪个.Net 4 GC正在运行,以及如何将GC切换到新的并发后台gc(如果不是),或者如何确认这些实际上是GC(Procmon不在Win2k3服务器中显示.Net工具。)
答案 0 :(得分:28)
我在我的博客上重新发布了这个答案:http://dave-black.blogspot.com/2012/04/how-to-determine-which-garbage.html
您可以通过两种方法确定您正在运行的GC版本:
你没有说你有什么样的应用程序。如果您正在运行控制台应用程序,WinForm应用程序或Windows服务,您将获得Workstation GC。仅仅因为您在服务器操作系统上运行并不意味着您将获得GC的服务器版本。如果您的应用程序未托管在多进程计算机上,则默认情况下将获得Workstation GC - Concurrent。如果您的应用程序托管在多进程计算机上,则默认情况下将获得ServerGC。
默认情况下,任何IIS或CLR自托管应用都将以ServerGC模式运行。
以下内容适用于任何给定的.NET托管进程:
无论GC模式如何,每个托管进程只有1个终结器线程。即使在并发GC期间,托管线程也会被挂起(阻塞)两次以执行GC的某些阶段。
很少有人知道即使您尝试设置GC的服务器模式,也可能无法在Server GC中运行; GC最终确定哪种模式最适合您的应用,如果确定您的ServerGC设置会对您的应用产生负面影响,则会覆盖您的设置。此外,在单处理器计算机上运行的任何托管CLR应用程序都将覆盖任何手动GC设置 - 在这种情况下,CLR将始终使用Workstation GC模式。
因此,在.NET 4.5+中,所有应用程序现在都具有后台GC 可用,无论它们使用哪个GC。
.NET Framework 4.7.1引入了垃圾收集(GC)中的更改以提高分配性能,尤其是对于大对象堆(LOH)分配。这是由于架构更改将堆的分配锁分为2,小对象堆(SOH)和LOH。进行大量LOH分配的应用程序应该看到分配锁争用的减少,并且看到更好的性能。这些改进允许LOH分配,而背景GC(BGC)正在扫描SOH。通常,LOH分配器在满足分配存储器的请求之前等待BGC扫描过程的整个持续时间。这可能会影响性能。您可以在PerfView的GCStats中观察到此问题,其中存在'LOH分配暂停(由于背景GC)> 200毫秒活动表。暂停的原因是'等待BGC线程免费列表'。此功能应有助于缓解此问题。
答案 1 :(得分:1)
您正在运行Windows的服务器版本,默认情况下您将获得垃圾收集器的服务器版本。哪个不进行背景收集,垃圾由多个线程收集,因此偶尔可观察到的暂停并不罕见。您可以使用app.exe.config文件强制使用工作站版本:
<configuration>
<runtime>
<gcServer enabled="false"/>
</runtime>
</configuration>
另请查看GC.RegisterForFullGCNotification()方法的文档,了解处理暂停的副作用的方法。
.NET 4.5版将支持服务器GC的后台集合。