IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

problème libération mémoire dû aux user control


Sujet :

Windows Forms

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 76
    Points : 33
    Points
    33
    Par défaut problème libération mémoire dû aux user control
    Bonjour,
    J'ai un problème de libération de mémoire sur l'utilisation de user control sur le compact framework 2.0.
    Lorsque j'appelle un formulaire avec un ou plusieurs user control, la mémoire utilisée augmente. Lorsque je quitte ce formulaire la mémoire n'est pas restituée...
    J'ai essayé un dispose de tous les composants, un remove sur les controls et un gc.collet() rien n'y fait la mémoire reste toujours allouée.
    Une augmentation conséquente de la mémoire utilisée est faite lors du premier appel au formulaire puis lors des autres appels, l'augmentation est moins significative (de l'ordre d'un vingtaine de KB).

    merci d'avance pour votre aide sur cette fuite de mémoire.

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 76
    Points : 33
    Points
    33
    Par défaut
    j'ai continué à chercher sur cette fuite de mémoire et il pourrait s'avérer que cela provienne des composants utilisant des images. Elles sont pourtant bien dispose, remise à null et gc.collet()...
    Si vous avez des idées de ce qui provoque ceci je ne trouve rien sur le net...

  3. #3
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    C'est normal. Le GC ne passe pas de façon déterministe ; il nettoie la mémoire quand le système lui demande de le faire.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 76
    Points : 33
    Points
    33
    Par défaut
    ok... mais le dispose et le fait de remettre les variables à null ne change pas le fait qu'il y est une fuite de mémoire. Comment faire pour nettoyer tout comme il faut ?

  5. #5
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Il n'y a rien dans ce que tu indiques qui permet de dire qu'il y une fuite de mémoire.

    Comme le dit Guulh, le gc n'étant pas déterministe, il n'a aucune raison de collecter les espaces chaques fois que quelque chose est "disposed" (si il le ferait cela enlèverait beaucoup d'interêt aux environnement managés, car cela serait contre productif en terme de perf ... comme l'est d'ailleurs ton appelle à gc.collect() a priori sans raison).

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 76
    Points : 33
    Points
    33
    Par défaut
    j'ai rajouté le gc.collect suite au recherche que j'ai faite sur le net...
    pourtant il y a bien une perte de mémoire car quand j'ouvre une première fois un formulaire il prends par exemple 3Mb et ne les rend pas... certes il s'agit peut être de DLL remontées en mémoire ou quelque chose comme ça mais après à chaque ouverture de ce même formulaire il reprend 20 à 30KB et ne les rend pas à la fermeture. Donc forcement au bout d'un moment d'utilisation ça plante !

  7. #7
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par grogui Voir le message
    Donc forcement au bout d'un moment d'utilisation ça plante !
    Ok, si ca plante c'est autre chose (mais ça tu ne l'avais pas dit).

    Accessoirement ça plante comment ?

    Sinon, utilises tu des resources non managées, par exemple ?

    Mais encore une fois appeler le gc.Collect ne sert à rien : où les objets ont été disposed normalement, et il effectuera sa recollection à un moment ou à un autre, ou ils ne le sont pas et tu pourras appeller 42000 fois gc.collect, cela n'aura pas plus d'effet que de pisser dans un violon.

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 76
    Points : 33
    Points
    33
    Par défaut
    alors en fait j'ai fait deux tests :

    Un premier formulaire avec un composant que j'ai créé qui utilise du code managé. A la première ouverture une allocation mémoire est faite qui est conservée lorsque l'on quitte. Cependant il ne reprend pas de mémoire aux autres ouvertures.

    Un second formulaire avec un composant qui est un user control et qui lui en revanche prend de la mémoire à chaque ouverture sans jamais la rendre. ce qui est problématique.

    Le problème que cela engendre est une incapacité à allouer d'autres objets.
    La mémoire dont on dispose sur l'appareil qu'on utilise est restreinte et donc on atteint la limite au bout d'un moment.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 76
    Points : 33
    Points
    33
    Par défaut
    Après de nouvelles investigations sur ce problème de mémoire cela survient lorsque je récupère une image à partir du resourceManager.
    je vous montre le code que j'emploie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    dans le program.cs : 
    string CurrentAssemblyName = Assembly.GetExecutingAssembly().GetName().Name;
    locRM = new ResourceManager(CurrentAssemblyName + ".Properties.Resources", typeof(TestMemory.Form1).Assembly);
    
    dans mon formulaire : 
    Image imageChip = null;
    imageChip = (Image)Program.locRM.GetObject("chipblue");
    
    imageChip.Dispose();
    imageChip = null;
    rien que de faire ceci, ça "mange" de la mémoire à chaque ouverture de formulaire et ça ne la rend jamais.

    Apparemment il s'agit d'un problème de libération de mémoire lors de l'utilisation d'image. Quand je récupère du texte de ce même resourceManager, il ne prend pas de mémoire à chaque ouverture donc cela est vraiment lié aux images...

  10. #10
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Si tu utilises souvent cette image, tu as intérêt à la stocker une bonne fois pour toutes, sans aller la chercher à chaque fois dans les ressources. Et donc tu ne la disposerais qu'à la fermeture de ton appli.

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 76
    Points : 33
    Points
    33
    Par défaut
    effectivement cela semble corriger le problème de perte de mémoire mais c'est dommage de ne pouvoir passer directement par les resources...

    il va falloir que je créé une classe avec tous mes objets de resource en static.
    de plus à chaque fois que je veux me servir de mon objet (ici l'image) il faut que j'utilise la méthode .clone() sinon il continu de prendre la mémoire...

  12. #12
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Je sais pas si c'est possible en dév PDA, mais avec le fx classique, Visual Studio a un designer de ressources, qui se charge de créer une classe qui hérite de ResourceManager et qui présente dans des propriétés les différentes ressoucres.

    Du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class TonAppliResources : ResourceManager
    {
      public TonAppliResources : base(CurrentAssemblyName + ".Properties.Resources", typeof(TestMemory.Form1).Assembly) { }
      public Image ChipBlue { get { return (Image)this.GetObject("chipblue"); } }
    // ou bien, comme je le suggérais, on stocke au premier appel
    private Image _chipBlue;
    public Image ChipBlue { get {
      if (_chipBlue == null)
        _chipBlue = (Image)this.GetObject("chipblue");
      return _chipBlue;
    } }
    }
    Tu vois l'idée ?

  13. #13
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 175
    Points : 25 116
    Points
    25 116
    Par défaut
    certes le gc passe quand il veut, mais un gc.collect libère la mémoire normalement

    par contre sur une appli en mode debug, il est tout à fait normal que la mémoire monte et ne redescende pas (jusqu'à l'outofmemory même), donc regarde la conf de ton projet

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 76
    Points : 33
    Points
    33
    Par défaut
    Guulh => je vois l'idée effectivement. cela corrige un morceau de ce problème de mémoire mais apparemment ce n'est pas tout...

    sperot51 => je génère mon code en release... je ne vois pas vraiment de quoi tu parle !?

  15. #15
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 175
    Points : 25 116
    Points
    25 116
    Par défaut
    Citation Envoyé par grogui Voir le message
    sperot51 => je génère mon code en release... je ne vois pas vraiment de quoi tu parle !?
    je dis juste que le mode debug est une fuite mémoire ^^
    donc si tu étais en mode debug, il n'y avait plus à chercher
    mais si meme en release tu as une fuite, il reste encore à la trouver je pense

  16. #16
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par sperot51 Voir le message
    je dis juste que le mode debug est une fuite mémoire ^^
    donc si tu étais en mode debug, il n'y avait plus à chercher
    mais si meme en release tu as une fuite, il reste encore à la trouver je pense
    ?
    Lors de mes tests en debug, un GC.Collect libère tout autant la mémoire qu'en mode Release.

  17. #17
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 175
    Points : 25 116
    Points
    25 116
    Par défaut
    certes ca dépend en partie du code
    mais en mode debug, des liens sont gardés vers toutes les instances créées
    donc le gc ne peux pas tout ramasser

  18. #18
    Membre averti
    Inscrit en
    Décembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Décembre 2008
    Messages : 256
    Points : 311
    Points
    311
    Par défaut
    Je pense qu'il faut arrêter de tergiverser revenir aux fondamentaux !

    Si chaque nouvel appel à la fenêtre augmente la mémoire totale consommée, et que celle-ci ne diminue jamais dans le temps, c'est que le GC ne collecte pas.
    Et s'il ne peut pas collecter, c'est qu'il reste des références vers des objets : soit des objets qu'on a créés soi-même, soit des ressources (éventuellement non managées) qui n'ont pas été disposées correctement.

  19. #19
    Membre averti
    Inscrit en
    Décembre 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Décembre 2008
    Messages : 256
    Points : 311
    Points
    311
    Par défaut
    Tu devrais essayer de tracer en pas à pas le code qui est exécuté lors de la fermeture de ton formulaire.
    Peut-être qu'il passe par des chemins où il n'y a pas de libération de certains de tes objets.

  20. #20
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par sperot51 Voir le message
    certes ca dépend en partie du code
    mais en mode debug, des liens sont gardés vers toutes les instances créées
    donc le gc ne peux pas tout ramasser
    Ah oui, il me semble que t'en avais parlé dans un autre thread il y a quelques mois, lien à l'appui... De ce que j'ai testé ce matin sur l'un de mes projets, je récupère des collections d'objets venant d'un serveur, que je convertis dans un type local et affiche dans une grille ; ces objets intermédiaires s'accumulent et font monter la consommation mémoire, mais un GC.Collect() les fait correctement disparaitre.
    Mais bon si t'as encore ce lien sous la main, ça m'intéresse

Discussions similaires

  1. Réponses: 0
    Dernier message: 02/05/2011, 17h37
  2. Réponses: 5
    Dernier message: 11/03/2010, 21h41
  3. Problème libération mémoire
    Par scary dans le forum Débuter
    Réponses: 2
    Dernier message: 08/05/2009, 22h12
  4. Problème conception de site (événement User Control)
    Par rad_hass dans le forum ASP.NET
    Réponses: 4
    Dernier message: 14/01/2009, 15h37
  5. problème libération mémoire après une DLL
    Par salseropom dans le forum C
    Réponses: 22
    Dernier message: 03/09/2008, 12h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo