我的ASP.NET MVC3应用程序使用Ninject通过包装器实例化服务实例。控制器的构造函数有一个IMyService参数,动作方法调用myService.SomeRoutine()。使用wsHttpBinding通过SSL访问服务(WCF)。
我有一个搜索例程,它可以返回如此多的结果,超过我在WCF中配置的最大值(在对象图中可以序列化或反序列化的最大项目数)。发生这种情况时,服务和客户端的应用程序池都会显着增长,并在请求结束后保持膨胀。
我知道我可以限制结果数量或使用DTO来减少传输的数据量。也就是说,我想解决看起来像是内存泄漏的问题。
使用CLR Profiler,我发现以下使用了大量的堆:
此外,如果我修改搜索例程以返回一个空列表(当NHibernate的东西仍在后台继续 - 通过日志验证),应用程序池大小保持不变。如果搜索例程在没有异常的情况下返回重要结果,则应用程序池大小保持不变。我相信当序列化对象列表并导致异常时会发生泄漏。
我升级到最新的Ninject,我使用log4net验证服务客户端是否已关闭或中止,具体取决于其状态(状态从未出现故障)。我发现唯一有趣的是服务包装器正在最终确定而没有明确处理。
我无法对此进行故障排除,以找出我的应用程序池在此方案中未释放内存的原因。我还应该注意什么?
更新:这是绑定...
<wsHttpBinding>
<binding name="wsMyBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:02:00" sendTimeout="00:02:00" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="999999" maxReceivedMessageSize="99999999"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="false"
allowCookies="false">
<readerQuotas maxDepth="90" maxStringContentLength="99999"
maxArrayLength="99999999" maxBytesPerRead="99999"
maxNameTableCharCount="16384" />
<reliableSession enabled="false" />
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
UPDATE#2 :这是Ninject绑定,但更奇怪的是错误消息。我的包装器没有正确设置MaxItemsInObjectGraph所以它使用了默认值。一旦我设置了这个,泄漏就消失了。当服务将序列化数据发送到客户端并且客户端因为它超过MaxItemsInObjectGraph而拒绝它时,客户端和服务似乎将序列化/反序列化数据保留在内存中。
Ninject Binding:
Bind<IMyService>().ToMethod(x =>
new ServiceWrapper<IMyService>("MyServiceEndpoint")
.Channel).InRequestScope();
错误消息:
InnerException消息是'可以的最大项目数 对象图中的序列化或反序列化为“ 65536 ”
这实际上并没有解决内存泄漏的问题,所以如果有人有任何想法,我仍然很好奇是什么导致了它。
答案 0 :(得分:1)
您如何处理代理客户端的创建和处理?
我发现与WCF相关的内存泄漏的最常见原因是错误处理WCF代理客户端。
我建议至少为您的客户打包using
块,如下所示:
using (var client = new WhateverProxyClient())
{
// your code goes here
}
这可以确保正确关闭和处理客户端,释放内存。
这种方法虽然有点争议,但它应该消除了从客户端创建中泄漏内存的可能性。
有关此主题的更多信息,请查看here。