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

Mr *_*ush 6 .net c# iis wcf web-services

我们有一个WCF服务作为BL服务.该服务处于混合传输模式,具有超过10个不同的端点,由BasicHttpBinding绑定,具有不同的合同和所有这些的相同地址.该服务在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>
    
    Run Code Online (Sandbox Code Playgroud)

Six*_*aez 5

AnkMannen指出,300MB并不罕见.大量使用的服务可以轻松达到约700MB或更高的平台.您对耗尽大多数可用服务器内存但未触发内存不足异常的服务的第二次观察可能是由于非默认配置值:

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

readerQuotas:
maxDepth="20000000"
maxStringContentLength="8192000"
maxArrayLength="16384000"
maxBytesPerRead="4096000"
maxNameTableCharCount="16384000"
Run Code Online (Sandbox Code Playgroud)

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


Mr *_*ush 5

经过长时间的搜索,我们发现了问题所在。我们的服务在工作单元模式中使用了很多逻辑单元。每个逻辑单元都继承自一个BaseLogic类。在BaseLogic单元中有一个Enterprise Library UnityContainer属性,它创建了一个工厂。每次调用都会创建该工厂的许多实例,将此属性更改为静态属性可以解决问题。