当物理> 95%时,为什么.NET不会将未使用的内存释放回操作系统?

时间:2015-02-19 18:33:03

标签: c# wcf iis memory-management garbage-collection

我们正在测试4进程WCF IIS应用程序(x3发行版本)的内存稳定性(泄漏),只需每隔1秒ping一次,就像Load Balancer一样。如果服务器上没有运行其他任何东西,它运行正常> 12小时。

但是,如果我们故意减少总可用内存(修复页面,减少物理内存,启动其他应用程序)并将物理内存使用率提高到97%并将其保留5分钟或更长时间,Windows通常会感知条件并关闭其中一个进程。请注意,如果将内存推至97%(使用固定页面文件),它也会失败。

但是,使用RedGate工具分析其中一个幸存进程的内存占用情况,可以看出:

RedGate Summary Tab

由于请求只是一个稳定的ping,因此当服务器缺乏时,.NET似乎没有实际的理由来保存269MB可用内存。大约50%的IIS进程似乎处于此状态(~1.8GB)。

App是针对.NET 4.0编译的,gcServer是真的。 IIS Gate检查设置为0%(minFreeMemoryPercentageToActivateService =" 0")虽然我们可能会在生产中将其设置为2%。

服务器是2008 R2,~4GB物理4GB固定页面,用4.0然后4.5.1测试(没关系)。

answer to a similar question by @atanamir声明:

  

"一旦你运行不足,.NET将把它的堆释放回操作系统   物理记忆。"

任何人都知道该声明的任何参考?它可能是特定版本的吗?

参考文献:

2 个答案:

答案 0 :(得分:5)

这不是你问的问题的答案(为什么),但它应该是实现你想要做的事情的一种方式。

.NET Framework 4.5有一些新功能 - source

  

一旦站点运行,它使用垃圾收集器(GC)堆可能是其内存消耗的重要因素。与任何垃圾收集器一样,.NET Framework GC在CPU时间(集合的频率和重要性)与内存消耗(用于新的,释放的或可释放的对象的额外空间)之间进行权衡。对于以前的版本,我们提供了有关如何配置GC以实现正确平衡的指导。   对于.NET Framework 4.5,可以使用工作负载定义的配置设置,而不是多个独立设置,可以启用以前推荐的所有GC设置以及为每个站点工作集提供额外性能的新调整< / strong>即可。例如,不需要设置gcServer,gcConcurrent等。

他们还指出here

  

调整GC以实现高密度Web托管:GC可以影响网站的内存消耗,但可以对其进行调整以实现更好的性能。您可以调整或配置GC以获得更好的CPU性能(减慢集合频率)或降低内存消耗(即更频繁的集合以更快地释放内存)[...]以实现每个站点更小的内存消耗(工作集)

要启用GC内存调整,请将以下设置添加到Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ aspnet.config文件和Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ aspnet.config文件中:< / p>

<configuration>
<!-- ... -->
<runtime>
<performanceScenario value="HighDensityWebHosting"  />
<!-- ... -->  

基本上,基于我所做的测试,我发现它将消耗更多的CPU,更少的内存,并使GC在清理和内存释放过程方面更具攻击性。 我们在基础架构(IIS 7.5,新的4.5框架)中测试了此设置,结果令人印象深刻。导致内存不足异常的高内存使用率不再是问题。

希望它有所帮助。

答案 1 :(得分:1)

atanamir提供的信息可以在MSDN page找到。

  

当满足下列条件之一时,就会发生垃圾收集:

     
    

系统物理内存较低。

         

托管堆上已分配对象使用的内存超过了可接受的阈值。在该过程运行时,该阈值会不断调整。

         

调用GC.Collect方法。几乎在所有情况下,您都不必调用此方法,因为垃圾收集器会持续运行。此方法主要用于独特的情况和测试。