ASP.NET MVC内存泄漏问题

3

背景: 使用Ninject 2.2.0.0 IoC、Repository模式和Service层的Asp.net项目(VB.Net)

Ninject绑定使用InRequestScope()

问题: 项目即将上线,但压力测试显示网站在使用后未能释放内存,导致内存消耗率过高。 举个例子: 每个用户实例在大约2分钟的业务处理中使用70到100 MB的内存,因此在不到10分钟的时间内,16个模拟用户就成功地导致了内存和CPU超载以及站点崩溃。 (服务器具有8GB RAM且没有其他重要进程正在运行)。

已尝试以下解决方案: 尝试在BaseController(由所有控制器继承)、基本Repository以及主数据库上下文中实现Using块并使用Dispose。

网站无法加载,因为DbContext立即被释放了,因此必须从Dispose中删除它。

使用ANTS Memory Profiler并没有什么效果,但ANTS Performance Profiler显示Ninject无法到达Dispose函数。它试图在C:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Infrastructure\Disposal文件夹中查找DisposableObject.cs。 找不到它所以崩溃了。ANTS Reflector从Ninject.dll反编译了相同的DisposableObject代码,所以不知道为什么它在不存在的默认目录中寻找它。

因此尝试升级Ninject从2.2.0.0升级到v3,使用Nuget PM> Install-Package Ninject.MVC3 经过一些修改,使其正常工作,但现在被困在ActionFilterAttribute上,它是版本2.2.0.0,使用NinjectFactoryController获取其内核绑定,如下所示:

Private _mailService As IEmailService

_mailService = New StandardKernel(New NinjectControllerFactory.QuickQuoteServices()).Get(Of IEmailService)()

现在对于Ninject.MVC3,NinjectFactoryController已被注释掉,所有绑定都在NinjectWebCommon.vb的register service部分中进行(VB代码来自第二个代码块,页面链接:https://gist.github.com/923618)。
因此,必须更改ActionFilterAttribute代码为:
<Inject()>
Private _mailService As IEmailService

(已注释掉NinjectFactoryController行)。

这将返回_mailService作为Nothing,因此实际上绑定没有起作用。

尽管使用这个新的Ninject.MVC3版本没有观察到任何内存改进,但ANTS内存分析器正常工作。

ANTS性能分析器正在工作而不崩溃,但似乎仍在错误的位置查找其他文件(如KernelBase.cs、ExtensionsForIEnumerableOfT.cs、Binding.cs等,所有这些都会给出错误,说明在c:\Projects\Ninject\ninject\src\Ninject...文件夹中查找此文件时未找到源代码)。

我们仍然无法找到内存泄漏/超载的起点,但很明显应用程序池在每次运行部分业务逻辑时积累70到100 MB的数据,然后这些内存直到总站点不活动20分钟(基于ISS 7空闲超时)才被释放,这对于网站崩溃前达到该阶段毫无帮助。

任何建议将不胜感激。

此致敬礼,

  • Abrar

编辑:

在得到一些指导后,我终于成功地使用了Ninject 3.0。

此外,使用属性声明可以解决ActionFilterAttribute中使用Ninject 3的问题,就像这样:

<Inject()>
    Public Property _mailService() As IEmailService
        Private Get
            Return m_mailService
        End Get
        Set(value As IEmailService)
            m_mailService = value
        End Set
    End Property
    Private m_mailService As IEmailService

现在Ninject 3已经在其中起作用,内存问题略有改善(即比以前释放了一些内存),但现在出现了一个新问题。CPU使用率非常高。这个问题甚至在Ninject从2.2升级到3.0之前就存在,但升级似乎对其没有任何影响。即使只有2-3个用户,CPU仍然会达到最大值,这使得网站无法响应,最终在使用约10分钟后崩溃。

欢迎提出任何想法。

此致敬礼,

  • AbrarHF

嗨Dene,通过删除.pdb文件,情况稍微得到了控制。无论如何,似乎这只是一个误导,因为Profiler本身似乎仍在工作。感谢您的指导。 - AbrarHF
问题已编辑:成功使用了Ninject 3.0并改善了内存,但现在CPU占用率过高导致网站崩溃。 - AbrarHF
1
你创建一个新的StandardKernel只是为了获取一个服务实例,这让我认为你正在错误地使用Ninject。在NinjectMVC3类中应该只有一个New StandardKernel。 - Remo Gloor
@Remo:此外,您能否为我们的CPU超载问题提供建议? 我认为这与Ninject本身无关,但是此问题(在问题编辑部分中提到)在解决方案使用Ninject 2.2.0.0时存在,并且在升级到Ninject 3.0后仍然存在。 我们无法弄清楚为什么它会达到CPU的最大值,因为我们已经查看了代码,似乎没有太多繁重的处理。 数学计算非常基本,我们的大多数Linq查询都已被For Each循环替换,因为它们应该更有效率。 - AbrarHF
@AbrarHF 我将我的初始评论转换为答案,以便这个问题不再是未回答的。 - Remo Gloor
显示剩余4条评论
1个回答

2

如果您只是为了获取服务实例而创建新的StandardKernel,那么我认为您正在错误地使用Ninject。

NinjectMVC3类中应该只有一个New StandardKernel。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接