现在在使用dotTrace后,我很确定这里存在内存泄漏,但在不知道应用程序的情况下很难100%确定.当我们用这个理论面对开发人员时,他们在30秒后解雇它,说“内存在.NET中自动处理”.如果最终确定数据,.NET肯定会收集48x~400MB的垃圾?
无论如何,我习惯使用WinForms.如何在ASP.NET中创建内存泄漏?是(仅)在.NET中使用Application和Session对象的唯一方法吗?
编辑
我已经发布了这个问题,了解到在请求处理程序中保存对象的静态引用(无论是Web服务类,Web表单还是其他)都会导致“泄漏”.可能不是这里正确的术语,但无论如何…这我不确定,因为我认为处理程序类在IIS的每次请求后被杀死并重新创建.
所以这样的代码:
public class SomeService : IService { public static List<RequestData> _requestDataHistory = new List<RequestData>(); public void SomeRequest(RequestData data) { _requestDataHistory.Add(data); } }
会迟早会使您的服务器崩溃.也许这对大多数人来说是显而易见的,但对我来说不是:-)
如果删除静态关键字,仍然不确定这是否会成为问题.是否在每次请求后处理实例?
解决方法
当然,如果应用程序没有正确处理非托管资源(如套接字,文件处理程序等),可能存在内存泄漏.查看操作系统对象(在任务管理器中,您可以启用句柄和用户对象列)以查看如何他们成长.
如您所述,应用程序或会话对象滥用也可能是一个原因.
我想知道为什么你会有48个应用程序池(工作进程).这太过分了,你完全不需要它.
GC管理每个进程的内存,每个进程400MB并不是那么多.将应用程序池的数量减少到nr.核心 – 1,然后压力测试应用程序.如果它增长太多,你可能会担心内存泄漏.
根据您的其他信息,是的,在这种情况下,历史列表将无限增长.每个应用程序域创建一次静态对象,直到appdomain存在为止.
我建议你不要随意删除static关键字,除非你知道你没有破坏某些应用程序逻辑.调查为什么要收集数据,以及它的用途.代码还有另一个问题 – 它不是线程安全的,当2个请求同时进入时,它的行为是未定义的,并且决定将数据添加到该列表.
最好将你的问题转移到stackoverflow.com,因为它是一个编程问题,而不是管理问题.
如果您无法控制该代码,并且真的只想解决您的内存问题,您可以将您的apppool设置为在X次请求之后回收,或者在它们获得超过Y内存量之后再循环 – 但同样,这不是真实解决方案