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 :

[C# 2.0] Problème pour vider une imagelist


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Mickaël
    Inscrit en
    Mai 2003
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Mickaël
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2003
    Messages : 106
    Par défaut [C# 2.0] Problème pour vider une imagelist
    Bonjour,

    Dans mon appli, je charge une imageList avec les images contenues dans un dossier (Environ 500). L'appli occupe a ce moment, 100Mo.

    A la fermeture, je parcours l'imageList et je fais un dispose sur chaque image, la mémoire utilisée augmente d'environ 60Mo par image que je dispose, jusqu'à l'exception fatale "out of memory".

    Normalement le dispose d'une image ne devrait pas faire grossir la mémoire non ?
    Pour tester, après chaque dispose j'ai ajouté un GC.Collect, la consommation de mémoire reste stable.. Par contre la libération des 500 images dure presque 1 minute.

    Connaissez-vous des solutions ou une méthode efficace pour vider une imageList ?

    Voilà la code de ma fonction de nettoyage :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     while ( list.Images.Count > 0 )
    {
       try
        {
             list.Images[ 0 ].Dispose();
               //           GC.Collect();
     
       }
       catch
       {
     
       }
     
       list.Images.RemoveAt( 0 );
    }
    Merci,

  2. #2
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    A la fermeture ...
    A la fermeture de l'application ? De l'écran utilisant le composant ImageList ?

    Dans les 2 cas de toute façon, inutile de boucler pour faire un Dispose de chaque image car :

    • on peut appeler la méthode Dispose du ImageList tout simplement
    • à la fermeture de l'application, la mémoire sera forcément réclamée
    • à la fermeture de l'écran le Dispose du Form sera appelé (sauf si non affiché ou affiché en ShowDialog, il faudra appeler la méthode explicitement à ce moment). La méthode Dispose du composant ImageList aussi donc

  3. #3
    Membre confirmé
    Homme Profil pro
    Mickaël
    Inscrit en
    Mai 2003
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Mickaël
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2003
    Messages : 106
    Par défaut
    Merci,

    D'après mes tests, Dispose sur l'imageList ne libère pas la mémoire des images de la liste. C'est aussi ce que j'ai pu lire sur le net.

    En réalité, ces images sont affichées dans un onglet, et je libère la mémoire lorsque l'utilisateur ferme un onglet. Ce n'est pas forcement à la fermeture de l'application.
    Si je ne libère pas la mémoire à ce moment là, la mémoire sera rapidement saturée si l'utilisateur ouvre plusieurs onglets.

  4. #4
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    N'est tu pas en train de réinventer la roue ?

    Je pense qu'un clear devrait suffire !
    Et apres tu peux faire un dispose de ton imagelist

  5. #5
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Ce qui est sûr c'est que tu peux éviter le problème de dépassement de mémoire. Le problème vient de ton traitement de nettoyage
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    while ( list.Images.Count > 0 )
    {
       try
       {
             list.Images[ 0 ].Dispose();
       }
       catch { } 
       list.Images.RemoveAt( 0 );
    }
    tu vas alors déclencher la création d'un nouveau tableau à chaque image (Array.Copy afin de copier les données dans un autre tableau de taille N-1). Histoire de valider mes dires, voici ce que l'on peut voir avec Reflector
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public virtual void RemoveAt(int index)
    {
        if ((index < 0) || (index >= this._size))
        {
            throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
        }
        this._size--;
        if (index < this._size)
        {
            Array.Copy(this._items, index + 1, this._items, index, this._size - index);
        }
        this._items[this._size] = null;
        this._version++;
    }
    cela va augmenter la mémoire à chaque création de tableau. Plus tu as d'images, plus tu vas recréer des tableaux, plus la mémoire va augmenter, la mémoire allouée pour les tableaux intermédiaires n'étant pas immédiatement réclamée.

    Alors qu'un simple
    ou encore, si le composant ImageList sert ailleurs (et donc le disposer serait source de problème)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    foreach (Image img in list.Images)
    {
        img.Dispose();
    }
    list.Images.Clear();
    permet d'éviter ce phénomène.

    Après si la mémoire ne baisse pas ce n'est pas forcément un problème, c'est que si Windows n'a pas besoin de mémoire alors le processus la garde au besoin à mon avis (quelqu'un confirmera peut être).

    Par exemple je lance un chargement d'image, je passe à 160Mo de mémoire pour le processus. Après libération des images je reste à 160Mo. Je refais un chargement, la mémoire augmente sur le coup mais à la fin je suis à 100-120Mo de mémoire pour le processus. Après d'autres chargement/libération le processus s'est stabilisé à 190Mo de mémoire.

  6. #6
    Membre confirmé
    Homme Profil pro
    Mickaël
    Inscrit en
    Mai 2003
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Mickaël
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2003
    Messages : 106
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    foreach (Image img in list.Images)
    {
        img.Dispose();
    }
    list.Images.Clear();
    J'ai essayé ce code pour vider l'imageList.
    Avec 500 images affichées, la mémoire occupée est d'envirion 100Mo.
    Lors de la boucle, la mémoire occupée atteint et dépasse 1Go... ce qui provoque une exception OutOfMemory.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème pour vider une ListBox
    Par djames37 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 07/08/2011, 19h13
  2. Problème pour vider une combobox multicolonne
    Par kgb1917 dans le forum Windows Forms
    Réponses: 11
    Dernier message: 31/01/2010, 23h58
  3. Réponses: 13
    Dernier message: 23/12/2004, 18h01
  4. [MSSQL] Problème pour sélectionner une seule occurence
    Par Tinfolley dans le forum Langage SQL
    Réponses: 4
    Dernier message: 02/07/2004, 09h02
  5. Réponses: 3
    Dernier message: 29/08/2003, 10h57

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