2012-11-19 6 views
6

Abbiamo un servizio WCF come servizio BL. Il servizio è in modalità Trasporto misto, ha più di 10 endpoint diversi, vincolati da BasicHttpBinding, con contratti diversi e lo stesso indirizzo per tutti loro. Il servizio viene eseguito sul relativo pool di applicazioni su IIS-7.Servizio WCF che raggiunge l'utilizzo di memoria elevata in prima chiamata

Il problema è che il servizio funziona bene, ma dopo la prima chiamata, anche l'ottenere il WSDL, l'utilizzo della memoria del w3wp.exe va dritto a 300 mega, l'utilizzo della memoria di servizio mantiene ad aumentare costantemente, presa in consegna tutta la memoria fisica del server (98 - 100%). Non abbiamo superato l'eccezione di memoria, ma questa situazione rallenta altre applicazioni e il servizio, quindi è necessario aggiornare manualmente il pool di applicazioni una volta ogni paio di giorni. Ho già provato a utilizzare lo strumento di profilatura della memoria e non ho trovato alcun indizio alla causa del problema.

Qualcuno ha riscontrato questo problema? e se sì, cosa hai fatto?

Ulteriori informazioni:

  • Il servizio BL si trova sopra un quadro DAL base di NHibernate, abbiamo già escluso la perdita di memoria è originario da lì.
  • file di configurazione

    <?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> 
    
+0

Ho avuto problemi di memoria con WCF che ha rifiutato di andare via. La documentazione intorno alla miriade di opzioni di configurazione per WCF è piuttosto scarsa IMO. Non sono mai arrivato al fondo e ho finito per scrivere il mio framework di remoting che mi ha rimesso in controllo del consumo di memoria. Spero che tu trovi una soluzione migliore. – spender

+0

come è la tua configurazione? in particolare intorno all'opzione objectItemsInGraph ecc? Stai correndo contemporaneamente? Quante sessioni attive ecc. Stai permettendo? Tutti questi hanno un effetto. – Chris

risposta

4

Dopo una lunga ricerca abbiamo trovato il problema. Il nostro servizio utilizzava molte unità logiche in un'unità di modello di lavoro. Ogni unità logica ereditata da una classe BaseLogic. Nell'unità BaseLogic è presente una proprietà Enterprise Library UnityContainer che ha creato una factory.Ogni chiamata ha creato molte istanze di questa fabbrica, cambiando questa proprietà in una proprietà statica ha risolto il problema.

3

Il primo salto iniziale per 300 MB è coerente con quello che ho visto nelle nostre applicazioni. Non ho davvero trovato un modo per diminuire quel numero, ma rimane a quel valore nel tempo.

Per la parte crescente della memoria sembra una perdita di memoria standard o almeno un problema di GC. Stai usando il framework di entità e hai fatto il tuo profilo con uno strumento come Red Gates Memory Profiler, non con il profiler VS incorporato?

È difficile dare una risposta più specifica in base alle informazioni nella domanda.

Nel frattempo, provare a utilizzare l'aggiornamento automatico IIS del pool di applicazioni. Impostalo su una soglia a tua scelta e lascia che gestisca automaticamente l'aggiornamento.

+0

So che la domanda è un po 'vaga, aggiungerò qualsiasi informazione necessaria. –

5

Il 300 MB non è insolito come nota AnkMannen. Il servizio pesantemente utilizzato può facilmente superare circa 700 MB o più. La tua seconda osservazione del servizio di consumare memoria server più disponibile ma non innescare un'eccezione di memoria è probabilmente dovuto al valori di configurazione non predefiniti:

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

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

in realtà si sta configurando WCF di consumare troppa memoria con la valori che hai scelto. A meno che non si sia verificata una condizione specifica che richiede la modifica del valore predefinito per uno qualsiasi di questi attributi, non modificarli. L'unico valore che cambio regolarmente è maxReceivedMessageSize da un valore predefinito di 64 KB a circa 1 o 2 MB, se inevitabile. Se si esegue regolarmente il routing di messaggi di dimensioni superiori a 3 MB, è necessario riconsiderare la progettazione del contratto dati. Molti dei problemi di prestazioni di cui è accusato WCF sono in realtà errori di configurazione e non problemi di prestazioni nella stessa WCF.

+0

Grazie per il tuo commento, sono a conoscenza di questo problema, lo abbiamo già verificato e questo non è il problema. –