2010-05-12 19 views
6

Ho un servizio wcf molto piccolo ospitato in un'app console.Perdite di memoria del servizio WCF

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

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

    } 
} 

e il suo essere chiamato come

using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client()) 
{ 
    client.DoService(new DoServiceRequest()); 
    client.Close(); 
} 

Si ricorda che il servizio è pubblicato sul basicHttpBindings.

Problema

Ora, quando ho eseguito sopra il codice client in un ciclo di 1000 ho trovato grande differenza tra "Tutti i byte Heap" e contatori delle prestazioni "Byte privati" (io ho usato .net memoria profiler). Dopo l'indagine ho trovato che alcuni degli oggetti non sono disposti correttamente di seguito sono elencati gli oggetti (1000 istanza non trovata sono stati trovati -> è uguale alle chiamate client)

(lo spazio dei nomi per tutti è System.ServiceModel. canali)

HttpOutput.ListenerResponseHttpOutput.ListenerResponseOutputStream 
BodyWriterMessage 
BufferedMessage 
HttpRequestContext.ListenerHttpContext.ListenerContextHttpInput.ListenerContextInputStream 
HttpRequestContext.ListenerHttpContext 

Domande Perché dobbiamo sacco di oggetti undisposed e come controllarli.

si prega di aiuto

+1

Sembra una perdita di libreria di sistema per me. Il codice client (come nel servizio scritto dall'utente) non tocca quei buffer e flussi e sembra che WCF non li stia eliminando. –

+0

Mabushar: Hai avuto fortuna con questo? Mi sembra di avere un problema simile. – bugfixr

+0

@bugfixr scusa fratello, ho notato il tuo messaggio oggi, non ricordo se sono riuscito a liberarmi di quelli, ma una cosa che ricordo è che ho spostato il framework 4.0 dal framework 3.5, mi ha aiutato parzialmente o completamente ricorda, ma mi ha aiutato in qualche modo. scusa per il ritardo nella risposta. –

risposta

0

Ho trovato la soluzione nel 2010 ma ho dimenticato di postarlo. In realtà ho perso la traccia esatta ma ricordo che si trattava di un bug della libreria .Net che è stato segnalato a Microsoft ed è stato riconosciuto da loro. Non ho il suo link, ma vorrei pubblicarlo non appena riesco a trovarlo. Ad ogni modo Microsoft ha risolto questo problema in .net 4.0 e questa è la soluzione esatta che ho seguito, so che per alcuni di voi potrebbe non essere possibile a causa del cambiamento nell'ambiente del server che a volte non è nelle tue mani.

4

si sta richiedendo una nuova istanza per ogni chiamata (InstanceContextMode = InstanceContextMode.PerCall). Se non si verifica alcun GC nelle 1000 chiamate, le istanze del servizio non verranno raccolte. WCF richiede di implementare IDisposable

Da MSDN : Discover Mighty Instance Management Techniques For Developing WCF Apps

Per-Call Services per-call servizi sono la modalità predefinita di istanze Windows Communication Foundation. Quando il tipo di servizio è configurato per l'attivazione per chiamata, un'istanza del servizio, un oggetto Common Language Runtime (CLR), esiste solo mentre è in corso una chiamata client. Ogni richiesta del cliente ottiene una nuova istanza di servizio dedicata. La Figura 2 illustra come funziona questa attivazione a chiamata singola.

Figure 2 Per-Call Instantiation http://i.msdn.microsoft.com/cc163590.fig02(en-us).gif

  1. Il client chiama il proxy e il proxy inoltra la chiamata al servizio .
  2. Windows Communication Foundation crea un'istanza di servizio e chiama il metodo su di esso.
  3. Dopo la chiamata al metodo restituisce, se l'oggetto implementa IDisposable, Windows Communication Foundation chiama IDisposable.Dispose su di esso.
+1

Ho visto questo articolo prima ed è vero che chiama il metodo Dispose automaticamente se ce n'è uno e questo è solo se hai aperto qualche risorsa da te e hai bisogno di ripulire in questo caso sei tenuto a pulirli da solo. Ma nel mio caso non ho risorse da pulire. Comunque ho già provato questo, ma lo stesso risultato. Inoltre vorrei dirvi che GC ha pulito l'heap ma la memoria nativa non è stata pulita a causa di quegli oggetti raccolti da UNDisposed. –

1

Per caso hai abilitato i contatori delle prestazioni? Come sotto?

<system.serviceModel> 
    <diagnostics performanceCounters="All" /> 
    .. 
</system.serviceModel> 

Nel paragrafo "Aumentare Dimensioni memoria per i contatori delle prestazioni", da questo link: http://msdn.microsoft.com/en-us/library/ms735098.aspx

c'è menzione di una "canaglia" Byte privati ​​conteggio quando i contatori delle prestazioni WCF sono attivate. Cambiarlo in ServiceSolo o disabilitarlo completamente (Off) potrebbe fare il trucco.