【发布时间】:2015-03-23 17:32:52
【问题描述】:
澄清问题(tl;dr)
在阅读和分析下面涵盖的所有结果后,问题似乎归结为 GC 在服务器模式下没有为我们的应用程序收集 Gen 0 堆,一旦切换到工作站模式,问题就会消失。
原始问题和详细信息
我的问题有点相关:This question 和this question。
我们最近在测试环境中的 .NET 应用程序中遇到了似乎是内存泄漏的问题,工作进程在负载下或在无负载时会逐渐攀升至 450MB 左右的使用量。
这个问题无法在我们的开发环境中复制,主要区别在于开发环境是物理服务器,而测试环境是由 Puppet 虚拟化和控制的(除此之外,我对环境本身了解不多) .
为了希望了解哪些对象占用了所有内存,我在测试服务器上运行了 Ants Memory Profiler,发现所有内存都处于未使用状态并且从未被释放。
在研究可能导致此问题的原因时,我遇到了this forum post,这又将我引导至this article。
我最终尝试了它推荐的配置,将 GC 置于工作站模式:
<configuration>
<runtime>
<gcServer enabled="false"/>
<gcConcurrent enabled="false"/>
</runtime>
</configuration>
在运行 iisreset 并重新运行我的内存分析后,问题完全消失了,这很好,但仍然不能真正解释最初发生的事情。
我确实做了更多阅读并找到了this SO question,这让我相信这种配置更改最终可能会损害我们应用程序的吞吐量。
所以我的问题是:什么会导致 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 堆大小的初始峰值要小得多,并在请求完成后返回基本为零(下图)。
对此进行更多搜索导致我找到another 更多相关的 SO 问题,但他的发现是这种内存使用不是问题,而在我的情况下,服务实际上需要至少手动重新启动一次天。
我还发现 this article 对这个问题有以下说法(这似乎几乎完美地描述了正在发生的事情:
在 64 位系统上,第 0 代可能有更多的对象,尤其是当您使用服务器垃圾收集而不是工作站垃圾收集时。这是因为在这些环境中触发第 0 代垃圾收集的阈值更高,第 0 代垃圾收集可以变得更大。当应用程序在触发垃圾回收之前分配更多内存时,性能会得到提高。
尽管问题仍然存在,在服务器模式下,第 0 代堆似乎从未被收集,而不是经常被收集。
【问题讨论】:
-
可能是一百万的任意数量。如果不了解您的应用程序、在其上运行的代码类型,甚至可能是代码本身,就很难说清楚。
-
只是一个想法,如果您在应用程序池上启用了多个工作进程并且您没有设置空闲超时,那么重负载可能会启动额外的工作进程,然后它们在不处于重负载时从不关机,因为它们不会闲置。
-
此外,如果您的代码未调用 dispose 来释放非托管资源,则可以分配 .Net 未使用的内存。例如。假设您打开了一个文件流,但没有处理该文件流并且它超出了范围。 GC 将清理它的所有 .net 组件,但非托管部分(windows api 中的文件句柄)仍将打开,并且 Antz Profiler 可能不会检测到正在使用的非托管资源。
-
@Ryios,我不认为这可能是代码问题,因为我在问题的顶部提到了一些原因,并且我在编辑中已经澄清了。
-
@Ryios,如果非托管资源泄漏,我相信我会在我的内存分析中看到这一点,我会看看我是否可以编辑我的分析截图足以发布。
标签: c# iis-7 garbage-collection