WCF服务内存泄漏

Mub*_*har 6 wcf memory-leaks .net-3.5

我在控制台应用程序中托管了一个非常小的wcf服务.

[ServiceContract]
public interface IService1
{
    [OperationContract]
    void DoService();
}

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class Service1 : IService1
{
    public void DoService()
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

它被称为

using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client())
{
    client.DoService(new DoServiceRequest());
    client.Close();
} 
Run Code Online (Sandbox Code Playgroud)

请记住,该服务发布在basicHttpBindings上.

问题

现在,当我在1000循环中执行上面的客户端代码时,我发现"所有堆字节"和"私有字节"性能计数器(我使用.net内存分析器)之间存在很大差异.调查后我发现一些对象没有正确处理下面是这些对象的列表(找到了1000个未发现的实例 - >等于客户端调用)

(所有这些的名称空间是System.ServiceModel.Channels)

HttpOutput.ListenerResponseHttpOutput.ListenerResponseOutputStream
BodyWriterMessage
BufferedMessage
HttpRequestContext.ListenerHttpContext.ListenerContextHttpInput.ListenerContextInputStream
HttpRequestContext.ListenerHttpContext 
Run Code Online (Sandbox Code Playgroud)

问题 为什么我们有很多不受约束的对象以及如何控制它们.

请帮忙

Pre*_*gha 5

您每次调用都请求一个新实例 (InstanceContextMode=InstanceContextMode.PerCall)。如果在 1000 次调用中没有发生 GC,则服务实例将不被收集。WCF 要求您实现 IDisposable

来自MSDN:发现用于开发 WCF 应用程序的强大实例管理技术

每次调用服务 每次调用服务是 Windows Communication Foundation 默认实例化模式。当为每次调用激活配置服务类型时,服务实例(公共语言运行时 (CLR) 对象)仅在客户端调用正在进行时才存在。每个客户端请求都会获得一个新的专用服务实例。图 2 说明了这种单次调用激活的工作原理。

图 2 Per-Call 实例化
(来源:microsoft.com

  1. 客户端调用代理,代理将调用转发给服务。
  2. Windows Communication Foundation 创建一个服务实例并在其上调用方法。
  3. 在方法调用返回后,如果对象实现 IDisposable,则 Windows Communication Foundation 对其调用 IDisposable.Dispose。

  • 我之前看过这篇文章,确实有的话它会自动调用 Dispose 方法,这只有在您自己打开了一些资源需要清理的情况下,您才需要自己清理它们。但就我而言,我没有资源可以清理。但是我已经尝试过这个但结果相同。此外,我想告诉你 GC 已经清理了堆,但是由于这些对象被 UNDisposed 收集而没有清理本机内存。 (2认同)

Mub*_*har 1

我在 2010 年找到了解决方案,但我忘了发布它。我实际上失去了确切的跟踪,但我记得这是 .Net 库错误,该错误已报告给微软并得到了他们的承认。我没有它的链接,但我会在找到它后立即发布它。不管怎样,微软已经在.net 4.0中解决了这个问题,这就是我遵循的确切解决方案,我知道对于你们中的一些人来说,这可能是不可能的,因为服务器环境的更改有时不在你们手中。