Jus*_*ica 6 c# iis-7 garbage-collection
澄清的问题(tl; dr)
在阅读和分析下面介绍的所有结果之后,问题似乎归结为GC在服务器模式下不为我们的应用程序收集Gen 0堆,一旦它更改为工作站模式,问题就会消失.
原始问题和细节
我们最近在我们的测试环境中遇到了.NET应用程序中的内存泄漏问题,工作进程在负载下或在无负载时会迅速升至450MB左右.
这个问题无法在我们的开发环境中复制,主要区别在于开发环境是物理服务器,而测试环境是由Puppet虚拟化和控制的(除此之外我对环境本身并不了解).
为了有希望看到哪些对象负责占用所有内存,我在测试服务器上运行了Ants Memory Profiler,我发现所有内存都保持未使用状态并且从未被释放.
在研究可能导致这种情况的原因时,我发现了这个论坛帖子,这反过来引导我阅读这篇文章.
我最后尝试了它建议的配置,将GC置于工作站模式:
<configuration>
<runtime>
<gcServer enabled="false"/>
<gcConcurrent enabled="false"/>
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)
在运行iisreset并重新运行我的内存分析后,问题完全消失了,这很好,但仍然没有真正解释首先发生的事情.
我确实做了一些阅读并发现了这个问题,这使我相信这种配置改变可能最终会对我们的应用程序的吞吐量产生不利影响.
所以我的问题是:什么会导致IIS工作进程累积大量未被垃圾收集的未使用内存?
编辑: 为了更清楚地澄清我的问题,我相信我们已经证明代码不对此负责,因为完全相同的代码在开发环境中不会遇到此问题.
以下是我在配置更改之前和之后对内存分析所拍摄的屏幕截图,这里没有很多信息,但图表确实很好地显示了内存趋势.

编辑2: 这是我可以收集的服务器规格,我可能会得到更多只需要时间.
开发环境:物理机CPU:单核内存:6GB
测试环境:虚拟机CPU:4个逻辑线程(我无法评论CPU数量)内存:8GB
Machine.Config文件的唯一区别是开发环境正在为端点和服务行为添加"Microsoft.VisualStudio.Diagnostics.ServiceModelSink.Behavior".
并且测试环境当前具有aspnet.config文件中先前提到的GC设置.
编辑3: 做了一些更多的分析并注意到我可以在Ants中添加更多的计数器,特别是我添加了"Gen 0堆大小",看起来这是问题的根源.当GC处于服务器模式时,当我触发测试时,我正在用于分析此行,立即跳转到~300MB,然后回到~230MB,但永远不会一直回落(下图).

在工作站模式下使用GC运行相同的分析会看到Gen 0堆大小具有小得多的初始峰值,并在请求完成时返回到基本为零(下图).

进行一些更多的搜索引导我到另一个更相关的SO问题,但是他的发现是这个内存使用是一个非问题,而在我的情况下,服务实际上需要每天至少手动重启一次.
我还发现这篇文章在这个问题上有以下说法(这似乎描述了几乎完美的情况:
第0代可能在64位系统上拥有更多的对象,尤其是当您使用服务器垃圾收集而不是工作站垃圾收集时.这是因为在这些环境中触发第0代垃圾收集的阈值更高,并且第0代集合可以变得更大.当应用程序在触发垃圾收集之前分配更多内存时,性能会得到改善.
虽然问题仍然存在,在服务器模式下,第0代堆似乎从未被收集,而不是经常收集.
小智 1
经过大量研究、阅读和分析,我已经能够证明我们的 IIS 内存使用实际上在标准范围内;这是使用 SysInternals Test Limit 实用程序将服务器的物理内存使用量推至接近最大值来完成的,一旦完成此操作,我们所有的应用程序都会释放其内存。
我们的测试环境中确实仍然存在某种内存问题,我需要调查,但此时我想我可以自信地说这是完全不相关的。
这个故事的寓意是不要假设问题报告的原因是正确的。
| 归档时间: |
|
| 查看次数: |
2253 次 |
| 最近记录: |