记忆与处理 ServiceHost 中的泄漏
我的服务应用程序中有一个 ServiceHost,每 60 秒与 1700 个客户端进行通信。当我启动服务时,它几乎立即攀升到大约 1500 个打开的句柄,然后在大约 5 分钟后继续添加另外 300 个(并在此之后继续继续前进。)
我查看了 ProcessExplorer,在拆分视图中,它显示了数百个名为“Device\Afd”的文件类型句柄 - 它代表用于通信的 TCP 套接字(我相信)。
我只是假设我的句柄泄漏与 ServiceHost 有关,因为它代表从 Process Explorer 观察到的最高句柄数。我想知道为什么该服务不关闭这些?我是否需要设置某种超时,或者我是否需要在某个地方主动关闭它们?
以下是我的 ServiceHost 的创建方式:
wcfObject = new WcfObject();
host = new ServiceHost(wcfObject, baseWcfAddress);
ServiceBehaviorAttribute attribute = (ServiceBehaviorAttribute)host.Description.Behaviors[typeof(ServiceBehaviorAttribute)];
attribute.ConcurrencyMode = ConcurrencyMode.Multiple;
attribute.InstanceContextMode = InstanceContextMode.Single;
在我的 app.config 中:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="WcfObject" behaviorConfiguration="DefaultBehavior">
<host>
<baseAddresses >
<!-- Defined in code -->
</baseAddresses>
</host>
<endpoint name="NetTcpEndPoint" address="" binding="netTcpBinding" bindingConfiguration="netTcpBinding" contract="IWcfObject"/>
<endpoint name="NetTcpMetadataPoint" address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="netTcpBinding" maxReceivedMessageSize="9655360" maxBufferSize="9655360" maxBufferPoolSize="524288">
<readerQuotas maxArrayLength = "932000" maxStringContentLength="900000" maxDepth="32"/>
<security mode="None"></security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultBehavior" >
<serviceMetadata httpGetEnabled="False" httpGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="True"/>
<serviceThrottling maxConcurrentCalls="50" maxConcurrentSessions="100" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I've got a ServiceHost in a service app that communicates with 1700 clients every 60 second. When I start the service, it climbs to about 1500 open handles almost immediately, then continues to add another 300 after about 5 minutes (and continues onward continuously after that.)
I've looked at ProcessExplorer and in Split view, it shows hundreds of handles of type File named "Device\Afd" - which is a representative of the TCP socket being used to communicate (I believe).
I'm only assuming that my handle leak is related to the ServiceHost because it represents the highest number of handles observed from Process Explorer. What I'm wondering is why doesn't the service close these? Do I need to set a timeout of some sort or do I need to actively close them myself somewhere?
Here's how my ServiceHost is created:
wcfObject = new WcfObject();
host = new ServiceHost(wcfObject, baseWcfAddress);
ServiceBehaviorAttribute attribute = (ServiceBehaviorAttribute)host.Description.Behaviors[typeof(ServiceBehaviorAttribute)];
attribute.ConcurrencyMode = ConcurrencyMode.Multiple;
attribute.InstanceContextMode = InstanceContextMode.Single;
And in my app.config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="WcfObject" behaviorConfiguration="DefaultBehavior">
<host>
<baseAddresses >
<!-- Defined in code -->
</baseAddresses>
</host>
<endpoint name="NetTcpEndPoint" address="" binding="netTcpBinding" bindingConfiguration="netTcpBinding" contract="IWcfObject"/>
<endpoint name="NetTcpMetadataPoint" address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="netTcpBinding" maxReceivedMessageSize="9655360" maxBufferSize="9655360" maxBufferPoolSize="524288">
<readerQuotas maxArrayLength = "932000" maxStringContentLength="900000" maxDepth="32"/>
<security mode="None"></security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultBehavior" >
<serviceMetadata httpGetEnabled="False" httpGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="True"/>
<serviceThrottling maxConcurrentCalls="50" maxConcurrentSessions="100" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您的具体问题已描述 此处。
有关解决方法,请参阅同一篇文章。请随时告知我们您的发现。
I think your specific problem is described here.
For a workaround, see the same post. Please keep us informed of your findings.
事实证明,我是从 [STAThread] 运行我的服务 - 每当应用程序使用 COM 调用时,除非您运行 [MTAThread] 模式,否则您可能会泄漏内存。
As it turns out, I was running my service from a [STAThread] - anytime an app uses COM calls, you'll potentially leak memory unless you are running [MTAThread] mode.