2010-05-12 9 views
6

J'ai un très petit service wcf hébergé dans une application de console.Fuites de mémoire de service WCF

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

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

    } 
} 

et son être appelé comme

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

S'il vous plaît rappelez-vous que le service est publié sur basicHttpBindings.

Problème

Maintenant, quand je fis au-dessus du code client dans une boucle de 1000 i trouvé grande différence entre « Tous les octets Heap » et les compteurs de performance « Octets privés » (i utilisé la mémoire .net profileur). Après enquête, j'ai trouvé certains des objets ne sont pas correctement disposés suivant sont la liste de ces objets (1000 instance non-disposées ont été trouvés -> est égale aux appels client)

(espace de noms pour tous est System.ServiceModel. canaux)

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

questions Pourquoi nous avons beaucoup d'objets et comment non aliéné les contrôler.

Aide S'il vous plaît

+1

Cela ressemble à une fuite de la bibliothèque système. Le code client (comme dans le service écrit par l'utilisateur) ne touche pas à ces tampons et à ces flux, et il semble que WCF ne les dispose pas. –

+0

Mabushar: Avez-vous eu de la chance avec ça? Je semble avoir un problème similaire. – bugfixr

+0

@bugfixr frère désolé j'ai remarqué votre message aujourd'hui, je ne me souviens pas si je pouvais me débarrasser de ceux mais une chose que je me souviens était que je suis passé à framework 4.0 du cadre 3.5, il a aidé partiellement ou totalement je ne souvenez-vous, mais cela m'a aidé d'une certaine manière. Désolé pour la réponse tardive. –

Répondre

0

J'ai trouvé la solution en 2010 mais j'ai oublié de la poster. J'ai effectivement perdu la trace exacte mais je me souviens que c'était un bug de la bibliothèque .Net qui a été rapporté à Microsoft et a été reconnu par eux. Je n'ai pas son lien mais je l'afficherais dès que je pourrais le trouver. Quoi qu'il en soit Microsoft a résolu ce problème dans .net 4.0 et c'est la solution exacte que j'ai suivie, je sais que pour certains d'entre vous cela pourrait ne pas être possible en raison d'un changement d'environnement serveur qui n'est parfois pas entre vos mains.

4

Vous vous demandez une nouvelle instance par appel (InstanceContextMode = InstanceContextMode.PerCall). S'il n'y a pas de GC dans les 1000 appels, les instances de service ne seront pas collectées. WCF vous oblige à mettre en œuvre IDisposable

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

services par appel services par appel sont le mode par défaut instanciation Windows Communication Foundation. Lorsque le type de service est configuré pour l'activation par appel, une instance de service, un objet Common Language Runtime (CLR), existe uniquement pendant qu'un appel client est en cours. Chaque requête client reçoit une nouvelle instance de service dédiée. La figure 2 illustre le fonctionnement de cette activation par appel unique.

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

  1. Le client appelle le proxy et le proxy transmet l'appel au service .
  2. Windows Communication Foundation crée une instance de service et appelle la méthode.
  3. Après le retour d'appel de la méthode, si l'objet implémente IDisposable , puis Windows Foundation Communication appelle IDisposable.Dispose sur elle.
+1

J'ai vu cet article auparavant et il est vrai qu'il appelle la méthode Dispose automatiquement s'il y en a et ce n'est que si vous avez ouvert une ressource par vous-même et devez nettoyer dans ce cas vous devez les nettoyer vous-même. Mais dans mon cas je n'ai aucune ressource à nettoyer. Cependant j'ai déjà essayé ceci mais le même résultat. De plus je voudrais vous dire que GC a nettoyé le tas mais la mémoire native n'est pas nettoyée car ces objets ont été collectés. –

1

Avez-vous, par hasard, activé les compteurs de performance? Comme ci-dessous?

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

Au paragraphe « Augmenter la taille de la mémoire pour les compteurs de performance », de ce lien: http://msdn.microsoft.com/en-us/library/ms735098.aspx

il y a mention d'un « voyous » Octets privés comptent lorsque les compteurs de performance WCF sont activés. Le changer en ServiceOnly ou le désactiver complètement (Off) peut faire l'affaire.