c# - WCF 服务在第一次调用时达到高内存使用率

标签 c# .net wcf web-services iis

我们有一个 WCF 服务作为 BL 服务。 该服务处于混合传输模式,有超过 10 个不同的端点,由 BasicHttpBinding 绑定(bind),具有不同的契约(Contract)和相同的地址。 该服务在 IIS-7 上的应用程序池上运行。

问题是,服务工作正常,但是第一次调用后,即使获取了WSDL,w3wp.exe的内存使用量直奔300兆,服务内存使用量不断增加,接管了所有服务器的物理内存 (98 - 100 %)。我们没有遇到内存不足异常,但这种情况会减慢其他应用程序和服务的速度,因此我们需要每隔几天手动刷新一次应用程序池。 我已经尝试使用内存分析工具,但没有找到任何导致问题的线索。

有人遇到过这个问题吗?如果是,你做了什么?

附加信息:

  • BL 服务位于基于 NHibernate 的 DAL 框架之上, 我们已经排除了内存泄漏源自那里的可能性。
  • 配置文件

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <appSettings>
        </appSettings>   
        <system.web>
            <compilation debug="true" targetFramework="4.0" />
            <httpRuntime maxRequestLength="20000" requestLengthDiskThreshold="20000" />
        </system.web>     
        <system.serviceModel>     
            <behaviors>
                <serviceBehaviors>
                    <behavior name="DefaultServiceBehavior">
                        <serviceMetadata httpGetEnabled="true" />
                        <serviceDebug includeExceptionDetailInFaults="true" />
                    </behavior>
                </serviceBehaviors> 
    
                <endpointBehaviors>
                    <behavior name="AnonymousBehavior">
                    </behavior>
                </endpointBehaviors>
          </behaviors>
    
          <bindings>
              <basicHttpBinding>
                  <binding name="SecureBinding" 
                   closeTimeout="00:10:00" 
                   openTimeout="00:10:00" receiveTimeout="00:10:00" 
                   sendTimeout="00:10:00" allowCookies="true" 
                   hostNameComparisonMode="StrongWildcard" maxBufferSize="65536000" 
                   maxBufferPoolSize="524288000" maxReceivedMessageSize="65536000" 
                   transferMode="Buffered">
                      <readerQuotas maxDepth="20000000"
                       maxStringContentLength="8192000"
                       maxArrayLength="16384000"
                       maxBytesPerRead="4096000"
                       maxNameTableCharCount="16384000" />
                          <security mode="None">
                              <transport clientCredentialType="None"/>
                          </security>
                  </binding>
             </basicHttpBinding>         
        </bindings>
    
    <services>
    <service name="BL.Services.MyService"
    behaviorConfiguration="DefaultServiceBehavior">
    
    <endpoint address=""
    binding="basicHttpBinding"
    bindingConfiguration="SecureBinding"
    bindingNamespace="Security/Anonymous"
    behaviorConfiguration="WithSecurityContextInspector"
    contract="BL.Services.Contracts.IAnonymousClaimsService" />
    
    <endpoint address=""
    binding="basicHttpBinding"
    bindingConfiguration="SecureBinding"
    bindingNamespace="Domain/App"
    behaviorConfiguration="WithSecurityContextInspector"
    contract="BL.Services.Contracts.IAppService" />
    
    <endpoint address=""
    binding="basicHttpBinding"
    bindingConfiguration="SecureBinding"
    bindingNamespace="Domain/App"
    behaviorConfiguration="WithSecurityContextInspector"
    contract="BL.Services.Contracts.IAttachmentService" />
    
    <endpoint address=""
    binding="basicHttpBinding"
    bindingConfiguration="SecureBinding"
    bindingNamespace="Domain/Site"
    behaviorConfiguration="WithSecurityContextInspector"
    contract="BL.Services.Contracts.ISecurityService" />
    
    <endpoint address=""
    binding="basicHttpBinding"
    bindingConfiguration="SecureBinding"
    bindingNamespace="Domain/Transaction"
    behaviorConfiguration="WithSecurityContextInspector"
    contract="BL.Services.Contracts.ITransactionService" />
    
    <endpoint address=""
    binding="basicHttpBinding"
    bindingConfiguration="SecureBinding"
    bindingNamespace="Domain/ActiveDirectory"
    behaviorConfiguration="WithSecurityContextInspector"
    contract="BL.Services.Contracts.IActiveDirectoryService" />
    
    <endpoint address=""
    binding="basicHttpBinding"
    bindingConfiguration="SecureBinding"
    bindingNamespace="Domain/Report"
    behaviorConfiguration="WithSecurityContextInspector"
    contract="BL.Services.Contracts.IReportService" />
    
    <host>
    <baseAddresses>
    <add baseAddress="//MyService.svc" />
    </baseAddresses>
    </host>
    </service>
    </services>
    
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
    <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <defaultDocument>
    <files>
        <add value="MyService.svc" />
    </files>
    </defaultDocument>
    </system.webServer>
    </configuration>
    

最佳答案

正如 AnkMannen 所说,300MB 并不罕见。频繁使用的服务很容易稳定在 700MB 左右或更多。您对消耗大部分可用服务器内存但未触发内存不足异常的服务的第二次观察可能是由于非默认配置值:

binding:
maxBufferSize="65536000"
maxBufferPoolSize="524288000"
maxReceivedMessageSize="65536000"
transferMode="Buffered"

readerQuotas:
maxDepth="20000000"
maxStringContentLength="8192000"
maxArrayLength="16384000"
maxBytesPerRead="4096000"
maxNameTableCharCount="16384000"

您实际上是在将 WCF 配置为使用您选择的值消耗过多的内存。除非您遇到需要更改任何这些属性的默认值的特定情况,否则不要更改它们。如果不可避免,我经常更改的唯一值是 maxReceivedMessageSize,从默认值 64K 更改为大约 1 到 2 MB。如果您经常处理大于 3 MB 的消息,您应该重新考虑您的数据协定设计。许多 WCF 被指责的性能问题实际上是配置错误,而不是 WCF 本身的性能问题。

关于c# - WCF 服务在第一次调用时达到高内存使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13451211/

相关文章:

ASP.NET - 使用 WCF Web 服务绑定(bind)和 AD 组时出现 IIS7 部署错误 500 24 50

c# - 向供应商独立的 IDataParameterCollection 添加参数的更简洁的方法?

c# - Windows 窗体内存泄漏

taskbar - 类似c#中的windows任务栏之类的东西

c# - WebClient AsyncUpload 进度百分比始终返回 50%

c# - 明确的 SSL/TLS 版本选择

c# - 从 C# WCF 服务返回具有动态维数的锯齿状数组

C# - 字符串到关键字

c# - 将 BlockUIContainer 从 FlowDocument 复制到剪贴板时如何设置自定义文本?

.net - asp.net core 2.1 中的共享资源本地化和简单注入(inject)器