Laden...

Programmspeicherauslastung beim einlesen von Bildern

Erstellt von Dr.Z vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.279 Views
Dr.Z Themenstarter:in
88 Beiträge seit 2007
vor 14 Jahren
Programmspeicherauslastung beim einlesen von Bildern

Hallo zusammen,

ich scanne einen Barcode und muss zu diesem Barcode im System Bilder suchen und in einer Miniaturansicht anzeigen.

Eigentlich alles soweit kein Problem. Das Einzige was mir aufgefallen ist, dass nach jedem Anzeigevorgang der Bilder die Speicherauslastung um 20MB (bei 4 Bildern) ansteigt und auch so bleibt - bis zum nächsten Anzeigen.

An sich nicht schlimm, wenn die Anwendung nur einmal täglich, oder nach jedem Gebrauch wieder geschlossen werden würde. Dies ist aber nicht der Fall, sie wird sehr oft am Tag benutzt werden.

Die Pictureboxen mit denen ich die Bilder Anzeige erzeuge ich zur Laufzeit dynamisch.
Als übergeordnetes Steuerelement nutze ich ein Panel und füge die PictureBoxen diesem zu.

Ich habe schon versucht, die erzeugten Pictureboxen vor dem nächsten Anzeigen zu löschen mit

MyPanel.Controls.RemoveAt(index)
als auch
das Komplette Pnael zu löschen und neu zu erzeugen, aber das ändert nichts an der Problematik, dass sich die Speicherauslastung meiner Anwendung nicht verringert.

Würde mich sehr über ein paar hilfreiche Tips freuen!

W
109 Beiträge seit 2009
vor 14 Jahren

Der Fehler liegt in Codezeile 183 😉
Ne Spaß, ich weiß es nicht. Wahrscheinilch schwer zu sagen bzw zu raten...
Was du aber mal machen könntest wäre mal den Codeausschnit posten, der für das Anzeigen der Bilder zuständig ist.

Mfg
WhiteGlove

Hallo, ich heiße Hein Blöd und bin Softwareentwickler

Dr.Z Themenstarter:in
88 Beiträge seit 2007
vor 14 Jahren

Zeile 183 gibts bei mir gar nicht 😉

Also, der Code sieht so aus:


private void CreatePreview(string dir, string pattern)
        {
            pgb_load.Value = 0;

            //entfernen der alten, nicht mehr benötigten PictureBoxen
            for (int i = 0; i < pnl_picture.Controls.Count; i++)
            {
                pnl_picture.Controls.RemoveAt(i);
                i--;
            }

            
            //filtern der Suchergebnisse
            List<string> files = new List<string>();
            files.AddRange(Directory.GetFiles(dir, pattern));

            for (int i = 0; i < files.Count; i++)
            {
                if (files[i].Contains("thumb"))
                {
                    files.RemoveAt(i);
                    i--;
                }
            }

            int j = 0;
            int Top = 0;
            int Left = 0;

            pgb_load.Maximum = files.Count;

            //Anzeigen der gefundenen Bilddaten
            //immer 4 pro Zeile
            for (int i = 0; i < files.Count; i++)
            {
                PictureBox pb = new PictureBox();
                pb.Image = Image.FromFile(files[i]);
                pb.Height = 90;
                pb.Width = 120;                

                ...
                Anordnen der Bilder
                ...

                pb.Top = Top;
                pb.Left = Left;
                pb.SizeMode = PictureBoxSizeMode.StretchImage;
                pnl_picture.Controls.Add(pb);
                pgb_load.Value++;
                Application.DoEvents();
                j++;
            }
        }

That's it. Nicht wirklich was kompliziertes in meinen Augen.

2.921 Beiträge seit 2005
vor 14 Jahren

Erzeuge doch ein Thumbnail von den gefundenen Bildern, wenn es eh nicht in der realen Größe angezeigt werden muss.

Offtopic:
Außerdem sollte das Application.DoEvents raus und falls Du einen Thread benötigen solltest, der entsprechende Code in den Threa ausgelagert werden.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

Dr.Z Themenstarter:in
88 Beiträge seit 2007
vor 14 Jahren

Danke für die Antwort.

Mit dem Thread hast du recht. Das mit dem Application.DoEvents() war nur die quick and dirty Kurzversion 😃

Habe das mit dem Thumbnail grade mal eingepflegt:


pb.Image = Image.FromFile(files[i]).GetThumbnailImage(120, 90, null, IntPtr.Zero);

Erste Erkennstnis: Programmwachstum besteht weiterhin.
Beobachtung:
Sowohl mit als auch ohne Thumbnail sinkt die Speicherauslastung irgednwann wieder ein auf ca. 40MB und beginnt dann wieder, bei jedem erneuten Anzeigen an zu steigen.

Habe ich sehr viele Bilder, sinkt die Auslastung zwischen durch wieder und steigt weiter an.
Dieses Spiel wiederholt sich so lange, bis alle Bilder angezeigt sind.

4.938 Beiträge seit 2008
vor 14 Jahren

Image.FromFile hat so seine Tücken, such mal hier im Forum danach - es gibt bessere Alternativen (z.B. mittels eines eigenen FileStream)...

Gelöschter Account
vor 14 Jahren

Sowohl mit als auch ohne Thumbnail sinkt die Speicherauslastung irgednwann wieder ein auf ca. 40MB und beginnt dann wieder, bei jedem erneuten Anzeigen an zu steigen.

... ja der taskmanager..... richtig?

das verhalten ist in .net normal und das wirst du auch nciht abstellen bzw sollst du nciht abstellen. freier speicher nützt dir ncihts und wenn deine anwedung etwas schneller läuft, weil er nciht jedesmal wieder freiräumen/umräumen muss, dann ist das nur dein vorteil.

Dr.Z Themenstarter:in
88 Beiträge seit 2007
vor 14 Jahren

Ja genau, der Taskmanager.
Also ist's eigentlich kein "Problem" im eigentlichen Sinne?

Habe mal ausprobiert, wie sich das Ganze mit eine sehr vielen Bildern verhält. Die Speicherauslastung geht immer bis ca. 450MB hoch und fängt dann wieder bei ca 30MB an. Dieses Spiel wiederholt sich so lange, bis alle Bilder angezeigt sind.

Gelöschter Account
vor 14 Jahren

Also ist's eigentlich kein "Problem" im eigentlichen Sinne?

korrekt.

Ja genau, der Taskmanager.

für die zukunft:
für memoryanalysen in .net nützt dir der taskmanager ncihts. wenn du die wirkliche speicherauslastung eines .net prozesses wissen willst, dann verwedne den processexplorer von sysinternals oder einen .net memoryprofiler.

generell ist wie gesagt dieses verhalten, das du beobachtest beabsichtigt und sogar erwünscht.

ist dein speicherdruck groß (=wenig freier speicher wegen anderen anwendungen), wird er auch nciht die 400 mb belegen, sondern schon entsprechend frücher wieder freiräumen, was allerdings wieder die performance ein wenig mehr belastet.

Dr.Z Themenstarter:in
88 Beiträge seit 2007
vor 14 Jahren

Vielen Dank für die Hilfe!

Werde mich mal mit dem genannten Programm auseinander setzen.