gpt4 book ai didi

wcf - 内存泄漏 - WCF 异常

转载 作者:行者123 更新时间:2023-12-02 04:02:46 24 4
gpt4 key购买 nike

我的 ASP.NET MVC3 应用程序使用 Ninject 通过包装器实例化服务实例。 Controller 的构造函数有一个 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 的东西仍在后台进行 - 通过日志记录验证),应用程序池大小保持不变。如果搜索例程无一异常(exception)地返回重要结果,则应用程序池大小保持不变。我相信当对象列表被序列化并导致异常时会发生泄漏。

    我升级到最新的 Ninject 并使用 log4net 来验证服务客户端是否已关闭或中止,具体取决于其状态(并且该状态从未出现故障)。我发现唯一有趣的是服务包装器正在完成并且没有显式处理。

    我很难解决这个问题,以找出为什么我的应用程序池在这种情况下没有释放内存。我还应该看什么?

    更新:这是绑定(bind)...
    <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 绑定(bind),但更奇怪的是错误消息。我的包装器没有正确设置 MaxItemsInObjectGraph,所以它使用了默认值。一旦我设置了这个,泄漏就消失了。似乎当服务将序列化数据发送给客户端并且客户端拒绝它时,客户端和服务将序列化/反序列化数据保留在内存中,因为它超过了 MaxItemsInObjectGraph。

    Ninject 绑定(bind):
    Bind<IMyService>().ToMethod(x => 
    new ServiceWrapper<IMyService>("MyServiceEndpoint")
    .Channel).InRequestScope();

    错误消息:

    The InnerException message was 'Maximum number of items that can be serialized or deserialized in an object graph is '65536'



    这实际上并不能解决内存泄漏问题,所以如果有人有任何想法,我仍然很好奇导致它的原因。

    最佳答案

    您如何处理代理客户端的创建和处置?

    我发现 WCF 相关内存泄漏的最常见原因是 WCF 代理客户端处理不当。

    我建议至少用 using 包裹您的客户。 block 有点像这样:

    using (var client = new WhateverProxyClient())
    {
    // your code goes here
    }

    这可确保客户端正确关闭和处理,从而释放内存。

    这种方法虽然有点争议,但它应该消除客户端创建时泄漏内存的可能性。

    看看 here有关此主题的更多信息。

    关于wcf - 内存泄漏 - WCF 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9418086/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com