C# IIS应用程序池,内存管理

C# IIS应用程序池,内存管理,c#,wcf,profiling,iis-7.5,.net-4.5,C#,Wcf,Profiling,Iis 7.5,.net 4.5,我在IIS 7.5上托管了一个RESTful WCF服务。当调用某个操作时,它几乎立即返回,但会启动一个复杂的任务,处理组合运算并打开内存中的大文件。在多次请求之后,应用程序池使用了大约50%的内存,尽管任务已经完成。IIS池何时回收内存?我试图调用GC.Collect(),但什么也没发生。有没有办法像这样评测应用程序?我尝试了几个探查器,但它们只显示IIS用来处理请求本身的.NET类 工作进程本身不会自行向操作系统释放内存。您可以将进程设置为按计划循环使用-这会重新启动进程,释放内存而不会干扰

我在IIS 7.5上托管了一个RESTful WCF服务。当调用某个操作时,它几乎立即返回,但会启动一个复杂的任务,处理组合运算并打开内存中的大文件。在多次请求之后,应用程序池使用了大约50%的内存,尽管任务已经完成。IIS池何时回收内存?我试图调用
GC.Collect()
,但什么也没发生。有没有办法像这样评测应用程序?我尝试了几个探查器,但它们只显示IIS用来处理请求本身的.NET类

工作进程本身不会自行向操作系统释放内存。您可以将进程设置为按计划循环使用-这会重新启动进程,释放内存而不会干扰正在运行的请求


不过,您可能不应该这样做-基本上.net会保留内存,以避免为以后的请求重新分配内存。该内存可在WCF进程内重用,如果未使用该内存,操作系统将对其进行分页,并允许在其他进程需要时重用该内存。有关更多详细信息,请参阅。

长时间运行的任务通常不适合web应用程序,因为它们会超时/挂起网站/API的响应能力
是否可以将后台任务配置为在IIS站点上异步运行?因此,您可以将这些缓慢的任务推送到队列中,并在后台处理它们

我认为进程中的内存使用是一个问题,但并不能说明全部情况,到目前为止,您已经设法分析了哪些内容?您是否有未关闭的连接延迟?您是否正在创建多个未被有效处置的类的实例?我希望更多地分析调用执行计划,而不是内存使用情况,因为它可能会导致更多关于项目剩余位置的调用


当你说50%内存时,我们实际上谈论的是多少mb?IIS在不需要放弃RAM时可能有点贪婪/懒惰

我几乎遇到过类似的问题,我使用Castle.Windsor作为IoC容器解决了这个问题,将svc客户端类添加到具有瞬态作用域的容器中,最后,我用以下内容装饰svc类: [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]

所有其他依赖绑定都添加了瞬态Livestyle,从而使它们由实例化器依赖。考虑到您使用的是大文件,我不确定这对您的情况是否有帮助,但如果其他一切都失败了,请尝试在大多数内存消耗器类上实现IDisposable,并检查是否在应该调用Dispose时调用了它


希望有帮助

你能展示一些代码,你是如何创建和关闭这些文件的吗memory@ShirazBhaiji不幸的是,我不能在这里发布代码,但我试图通过将相同的代码添加到简单的应用程序中来分析它,但没有发现任何泄漏。旁注:不清楚您期望/抱怨什么-如果您的操作仍在进行中,为什么您期望对象被释放?您是否有理由相信,在所有“复杂任务”完成后,仍有大量托管内存被使用(不要查看任务管理器,因为它没有显示%的可用托管内存…@AlexeiLevenkov,而我的所有复杂任务完成任务管理器显示99%的服务器内存被iis池使用)。我甚至不能启动另一个web服务。。。而且这个系统速度非常慢……我认为你真的无法从中得到任何有用的东西,所以在这一点上——当你认为它已经完成时,你需要用一个“复杂任务”抓取minidump,并对它进行分析,看看是否有你不期望和喜欢的对象。不要等到流程消耗了所有资源——查看巨大的迷你转储一点也不有趣。请注意,您通常不赞成这样做—在IIS中运行不处理请求的进程是一种值得怀疑的方法。正如我前面所说,请求本身的处理速度非常快。如果我回收一个池-由请求启动的进程将死亡。具体问题是什么,您是遇到与内存相关的错误,还是只是在任务管理器中观察到内存使用率高?如果您只看到进程保留内存而没有其他错误,那么这是正常的行为,您不应该尝试更改它。顺便说一句,如果您有一个长时间运行的进程超出了web请求的范围,那么工作进程可能不是运行它的最佳位置,除非您已采取步骤停止IIS自动循环该进程。是的,由请求启动的进程是长时间运行的。该服务消耗大量内存(我在任务管理器中看到),我需要立即启动另一个服务,但没有内存来执行此操作。因此,在处理一定数量的请求后,您是否会出现错误?记录了什么消息?@QuéPadre这就是web服务器不应运行后台任务的原因,azure设计了队列和工作者角色。您可以创建另一个进程,让IIS循环,并且您的进程必须在完成一个长任务后停止。任何占用更多内存的任务都必须在完成后自行终止。进程终止时Windows将释放内存。我不太确定,但我认为默认的WCF服务工厂会将客户端svc类返回为singleton。这里50%是32 Gb…=)我将代码复制到一个控制台应用程序,并使用了多个分析器。因此,基本上这个应用程序的功能完全相同,但没有泄漏。=)它可能没有泄漏,只是在泄漏之前不释放不需要的东西。您能将使用的方法提取到dll中,然后从服务调用它吗?它可能有助于更好地分析应用程序,即使只是模拟服务上的一些初始负载。这将显示未关闭的连接、堆上未正确处理的大型对象以及未打开的引用等情况。一旦你有了这些,你就可以查看网站本身,看看是否有什么东西没有被显示出来