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

C# Discussion :

DrawImage et memoire


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 63
    Par défaut DrawImage et memoire
    Bonjour,

    J'ai construit une classe heritée de Panel pour dessiner des courbes (un peu à la maniere d'Excel, Matlab etc). Mon probleme c'est la quantite de memoire que consomme mon application, en particulier lors des changements de taille de la fenetre. A chaque passage d'une fenetre reduite (environ 1/4 de l'ecran) à la fenetre en plein ecran, mon application consomme 6 Mo de RAM en plus. Et si je continue a alterner entre les tailles il n'est pas rare que j'arrive à près d'1 Go de RAM pour une fenetre n'affichant que 9 panels...
    Biensur, a partir d'un moment le framework (je sais pas si c'est comme ca que ca s'appelle) fait le menage et la memoire utilisée par mon application retourne dans la normale, mais j'aimerais pouvoir optimiser mon code si possible.

    Voici un bout de mon code:

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (objBitmap != null)
            {
                Graphics g = this.CreateGraphics();
                g.DrawImage(objBitmap, 0, 0, this.Width, this.Height);
            }
        }
     
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            DrawGraphImage();
        }
     
     
        private void DrawGraphImage()
        {
            int i;
            objBitmap = new Bitmap(this.Width, this.Height);
            g = Graphics.FromImage(objBitmap);
     
            //White background
            g.FillRectangle(new SolidBrush(Color.White), 0, 0, this.Width, this.Height);
     
            if (wafeForms.Count != 0)
            {
                //Axes
                g.DrawLine(axePen, this.marginLeft, this.Height - yMargin, this.Width - this.marginRight, this.Height - yMargin);
                g.DrawLine(axePen, this.marginLeft, this.yMargin, this.marginLeft, this.Height - yMargin);
     
                double[,] markYArray = GetYMarkers();
                double[,] markXArray = GetXMarkers();
     
                for (i = 0; i < markYArray.GetUpperBound(0) + 1; i++)
                {
                    g.DrawLine(axePen, this.marginLeft - 5, this.Height - this.yMargin - (int)Math.Round(markYArray[i, 0]), this.marginLeft, this.Height - this.yMargin - (int)Math.Round(markYArray[i, 0]));
                    g.DrawString(markYArray[i, 1].ToString(), Font, new SolidBrush(Color.Black), this.marginLeft - 30, this.Height - this.yMargin - (int)Math.Round(markYArray[i, 0]) - 5);
                }
     
                for (i = 0; i < markXArray.GetUpperBound(0) + 1; i++)
                {
                    g.DrawLine(axePen, this.marginLeft + (int)Math.Round(markXArray[i, 0]), this.Height - this.yMargin, this.marginLeft + (int)Math.Round(markXArray[i, 0]), this.Height - this.yMargin + 5);
                    g.DrawString(markXArray[i, 1].ToString(), Font, new SolidBrush(Color.Black), this.marginLeft + (int)Math.Round(markXArray[i, 0]), this.Height - this.yMargin + 10);
                }
     
                //Draw waveforms
                foreach (WaveForm wf in wafeForms)
                {
                    double xS = GetXScale(wf.length);
                    double yS = GetYScale();
     
                    int modx = 1;
                    for (i = 0; i < wf.length - modx; i += modx)
                    {
                        g.DrawLine(wf.pen, (int)Math.Round((wf.xScale[i] - minX) * xS) + this.marginLeft, this.Height - (int)Math.Round((wf.data[i] - minY) * yS) - this.yMargin, (int)Math.Round((wf.xScale[i + modx] - minX) * xS) + this.marginLeft, this.Height - (int)Math.Round((wf.data[i + modx] - minY) * yS) - this.yMargin);
                    }
                }
            }
     
            this.Refresh();
        }
    Je me demande si ca ne vient pas de la ligne suivante dans mon override de OnPaint:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    g.DrawImage(objBitmap, 0, 0, this.Width, this.Height);
    Je connais pas bien tous les meandres du C# mais je pense que je continue de superposer des images et qu'elles restent en memoire jusqu'a ce que la machine virtuelle se rende compte que les precedentes ne servent plus à rien et les efface.

    Des idées pour eviter de monter si haut en consommation de memoire?

    Merci.

  2. #2
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Par défaut
    salut

    1/ Tu peux détruire ton objImage avant de faire un new, ca aider le garbage collector à faire son boulot...

    2/ le New du solidbrush n'est pas terrible car là encore, le GC va devoir réflechir pour travailler. Le plus simple est de créer ta solidbrush soit comme membre privé de ta classe soit de faire un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SolidBrush d = ...
     
    TON TRAVAIL
     
    d.Dispose();
    3/ Dans le OnPaint(), e.Graphics te donne directement le contexte graphique, donc, l'appel à CreateGraphics est inutile et couteux pour rien.

    Voilà... avec ces remarques, ca devrait diminuer le travail du GC et donc, éviter la croissance trop rapide et trop importante de ta consommation mémoire

  3. #3
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 63
    Par défaut
    Merci pour ton aide, ca m'a permis de trouver le problème.

    Je ne sais bien pas pourquoi car je ne comprends pas trop comment fonctionne le garbage collector, mais ca venait de:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    private void DrawGraphImage()
        {
            int i;
            objBitmap = new Bitmap(this.Width, this.Height);
     
            g = Graphics.FromImage(objBitmap);
     
     
            ...
         }
    le g etait membre privé de ma class et continuait de grossir. Je l'ai passé en simple variable de la fonction, il continuait toujours de grossir. J'ai donc mis un g.Dispose() à la fin et tout va bien maintenant

  4. #4
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Par défaut
    les remarques sur les SolidBrush est cependant toujours valable

  5. #5
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 63
    Par défaut
    Elles ont été prises en compte

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

Discussions similaires

  1. [LG]Mémoire dynamique
    Par FJUILLET dans le forum Langage
    Réponses: 5
    Dernier message: 10/02/2004, 11h15
  2. [langage] Problème de mémoire
    Par And_the_problem_is dans le forum Langage
    Réponses: 6
    Dernier message: 22/07/2003, 16h17
  3. [swing] probleme de memoire
    Par leBigouden dans le forum AWT/Swing
    Réponses: 6
    Dernier message: 23/05/2003, 14h19
  4. gestionnaire de memoire
    Par elone dans le forum C
    Réponses: 2
    Dernier message: 23/01/2003, 00h31
  5. récupérer la memoire et tableau dynamique
    Par Guigui_ dans le forum Langage
    Réponses: 6
    Dernier message: 06/01/2003, 08h02

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