我们有一个泄漏内存的大型asp.net应用程序。 Perfmon显示此泄漏位于托管内存中,因为W3WP专用字节以与所有堆中的字节相同的速率增长。我还可以看到Gen 2垃圾收集正在运行,但Gen 2堆大小继续增长。
我在WinDbg中进行了内存转储并进行了分析,可以看到很多类型的对象。字符串是最大的类型,字符串大小的20%由51个对象组成。
转储这些大字符串会显示从控件或整个页面输出的html。在这些上运行!gcroot显示根对象的类型为System.Text.RegularExpressions.Regex或System.Web.RegularExpressions.GTRegex。
有关可能发生的事情或我如何进一步调查的任何想法?
谢谢,西蒙
答案 0 :(得分:2)
如何使用dotTrace Memory或ANTZ Memory Profiler等内存分析器?这两种产品都是限时试用版。
答案 1 :(得分:2)
字符串是堆上最常见的类型并不奇怪。例如,如果您有10个HashSet,每个包含1000个字符串,则转储将显示您的堆上有10个HashSet,但是有100 000个字符串。许多对象包含一个或多个字符串。因此,转储中显示的字符串数是堆上所有对象的所有字符串的总和,这往往很多。
但是,如果你的堆上有很多System.Text.RegularExpressions.Regex,那很可能是你内存问题的根源。 .NET中的正则表达式倾向于占用大量资源。因此,我的建议是你通过你的代码,并试图找到任何过度使用正则表达式。此外,请确保正在处理对Regex对象的任何引用,也就是说,对Regex对象的引用不会保持活动状态。这样,垃圾收集器可以确保正确释放正则表达式对象。
祝你好运!答案 2 :(得分:0)
理论上,如果不使用非托管资源,在asp.net中导致内存泄漏应该非常困难。如果所有内容都是单线程的,那么当页面生命周期完成时,对托管资源的所有引用都应该可以自由地进行垃圾回收。您是否正在解雇工作线程以执行任何操作并且这些线程是否继续超出页面的生命周期?或者你是否有任何长时间运行的进程作为Web方法暴露,可以被异步启动并且只是需要很长时间才能运行并被重复调用直到内存已满?