【发布时间】:2012-02-23 17:30:52
【问题描述】:
我的 ASP.NET MVC3 应用程序使用 Ninject 通过包装器实例化服务实例。控制器的构造函数有一个 IMyService 参数,操作方法调用 myService.SomeRoutine()。使用 wsHttpBinding 通过 SSL 访问服务 (WCF)。
我有一个搜索例程,它可以返回很多结果,以至于超过了我在 WCF 中配置的最大值(对象图中可以序列化或反序列化的最大项目数)。发生这种情况时,服务和客户端的应用程序池都会显着增长,并且在请求结束后仍然很臃肿。
我知道我可以限制结果的数量或使用 DTO 来减少传输的数据量。也就是说,我想修复似乎是内存泄漏的问题。
使用CLR Profiler,我看到大部分堆被以下使用:
- System.RunTime.IOThreadTimer.TimerManager
- System.RunTime.IOThreadTimer.TimerGroup
- System.RunTime.IOThreadTimer.TimerQueue
- System.ServiceModel.Security.SecuritySessionServerSettings
- System.ServiceModel.Channels.SecurityChannelListener
- System.ServiceModel.Channels.HttpsChannelListener
- System.ServiceModel.Channels.TextMessageEncoderFactory
- System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder
- System.Runtime.SynchronizedPool
- System.Runtime.SynchronizedPool.Entry[]
- ...TextMessageEncoderFactory.TextMessageEncoder.TextBufferedMessageWriter
- System.Runtime.SynchronizedPool.GlobalPool
- System.ServiceModel.Channels.BufferManagerOutputStream
- System.Byte[][]
- System.Byte[] (92%)
此外,如果我修改搜索例程以返回一个空列表(而 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>
更新 #2:这是 Ninject 绑定,但更奇怪的是错误消息。我的包装器没有正确设置 MaxItemsInObjectGraph,所以它使用了默认值。一旦我设置了这个,泄漏就消失了。当服务将序列化数据发送给客户端并且客户端拒绝它时,似乎客户端和服务将序列化/反序列化数据保留在内存中,因为它超过了 MaxItemsInObjectGraph。
Ninject 绑定:
Bind<IMyService>().ToMethod(x =>
new ServiceWrapper<IMyService>("MyServiceEndpoint")
.Channel).InRequestScope();
错误信息:
InnerException 消息是 '最大项目数 对象图中的序列化或反序列化是 '65536'
这实际上并不能解决内存泄漏问题,所以如果有人有任何想法,我仍然很好奇是什么原因造成的。
【问题讨论】:
-
包装器使用什么绑定?
-
@Remo:我在上面添加了绑定 - 谢谢!
-
对不起,我不够清楚。我的意思是用于创建包装器的 Ninject Binding。尤其是范围很有趣。
-
如果您使用的是 Ninject 和 Ninject.MVC2 版本 >= 2.2,则包装器应该在 MVC 请求的末尾进行处理
标签: wcf asp.net-mvc-3 memory-leaks ninject