所以我们正在testing由外部公司开发的ASP.NET应用程序。 我们每秒处理大约50个请求,大约半小时后,48个工作进程(w3wp.exe)中的每个进程都高达大约400 MB并计数。 在IIS7上运行。
在干预dotTrace之后,我相当肯定这里有一个内存泄漏,但是如果不知道应用程序,很难100%确定。 当我们用这个理论面对开发人员的时候,他们在30秒之后解释了这个问题,说“像.NET一样自动处理内存”。 如果是最终的数据,.NET将会有垃圾收集48x400MB。
无论如何,我习惯于使用WinForms。 如何在ASP.NET中创build内存泄漏? (误)在.NET中使用应用程序和会话对象的唯一方法?
编辑
我已经发布了这个问题,得知在请求处理程序中持有对象的静态引用(无论是Web服务类,Web表单还是其他)都会导致“泄漏”。 也许这里不是正确的名词,但无论如何…这是我不确定的,因为我认为处理程序类在IIS的每个请求后被杀死和重新创build。
所以这样的代码:
public class SomeService : IService { public static List<RequestData> _requestDataHistory = new List<RequestData>(); public void SomeRequest(RequestData data) { _requestDataHistory.Add(data); } }
将迟早会崩溃你的服务器。 也许这对大多数人来说是显而易见的,但不是对我来说:-)
如果你删除了static关键字,仍然不确定这是否会成为问题。 在每个请求之后是否处理实例 ?
开发者可能是对的。 在.Net世界中,垃圾回收和释放内存在需要时发生。 也就是说,如果应用程序有足够的内存,它可能会消耗越来越多,直到操作系统不允许更多的分配。 除非真的引起问题,否则你不应该担心。
当然,如果应用程序没有正确处理非托pipe资源(如套接字,文件处理程序等),可能会有内存泄漏。查看操作系统对象(在任务pipe理器中,可以启用句柄和用户对象列),以查看他们成长。
正如你所说,应用程序或会话对象滥用也可能是一个原因。
我想知道为什么你会有48个应用程序池(工作进程)。 这是矫枉过正的,你根本不需要这个。
GCpipe理每个进程的内存,每个进程400MB没有那么多。 减less应用程序池的数量。 核心 – 1,然后对应用程序进行压力testing。 如果它增长太多,你可能会担心内存泄漏。
根据您的额外信息,是的,在这种情况下,历史列表将无限增长。 每个应用程序域都创build一次静态对象,直到应用程序生存。
我不build议你任意删除static关键字,除非你知道你不打破某些应用逻辑。 调查为什么要收集这些数据,以及它的用途。 代码还有另一个问题 – 它不是线程安全的,当两个请求同时进入时,它的行为是不确定的,并决定将数据添加到该列表中。
更好的移动你的问题到stackoverflow.com,因为这是一个编程问题,而不是pipe理问题。
如果你不能控制这个代码,并且真的只想解决你的内存问题,你可以设置你的应用程序在X请求之后或者在得到超过Y的内存之后回收 – 但是,这不是真正的解决
从一般意义上说,内存泄漏是编码逻辑的负面/未预料的结果,它不会正确释放(或不再使用)资源,也不会为新的/持续的使用/处理需求保留额外的资源。 整个资源“足迹”继续增长,即使通过正确使用和释放资源的适当“清理”到位,实际需求也不一定会增加。
简而言之,它不限于逻辑编程“滥用”,可能来自资源pipe理的错误假设或缺乏资源pipe理。