Sup*_*man 9 .net garbage-collection
我正在Windows Server 2003 x64(2x Xeon 4核心触发器)上运行一个大型.net 4.0 x86应用程序,并且遇到了我的应用程序〜每天2-3次冻结30秒,然后恢复正常运行的问题.该应用程序每周只重启一次,消耗400-800 MB的内存,所以我假设这些冻结是垃圾收集.我只看到日志中的冻结,而不是现场,或者我会检查任务管理器确认.
我试图找出哪个.Net 4 GC正在运行,以及如何将GC切换到新的并发背景gc(如果不是),或者如何确认这些实际上是GC(Procmon不显示.Net) Win2k3服务器中的仪器).
Dav*_*ack 29
我在我的博客上重新发布了这个答案:http://dave-black.blogspot.com/2012/04/how-to-determine-which-garbage.html
您可以通过2种方法确定您正在运行的GC版本:
你没有说你有什么样的应用程序.如果您正在运行控制台应用程序,WinForm应用程序或Windows服务,您将获得Workstation GC.仅仅因为您在服务器操作系统上运行并不意味着您将获得GC的服务器版本.如果您的应用程序未托管在多进程计算机上,则默认情况下将获得Workstation GC - Concurrent.如果您的应用程序托管在多进程计算机上,则默认情况下将获得ServerGC.
默认情况下,任何IIS或CLR自托管应用程序都将以ServerGC模式运行.
以下内容适用于任何给定的.NET托管进程:
无论GC模式如何,每个托管进程只有1个Finalizer线程.即使在并发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线程免费列表'.
您运行在服务器版本的 Windows 上,默认情况下您将获得服务器版本的垃圾收集器。它不进行后台收集,垃圾由多个线程收集,因此偶尔可观察到的暂停并不罕见。您可以使用 app.exe.config 文件强制使用工作站版本:
<configuration>
<runtime>
<gcServer enabled="false"/>
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)
另请查看GC.RegisterForFullGCNotification()方法的文档,了解处理暂停副作用的方法。
.NET 4.5 版将支持服务器 GC 的后台收集。