Laden...

Speicherlecks bei BitmapImage

Erstellt von vbtricks vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.261 Views
vbtricks Themenstarter:in
205 Beiträge seit 2006
vor 15 Jahren
Speicherlecks bei BitmapImage

Salut,

für einen Prototyp habe ich in meinem Fenster ein Raster von Image Controls angelegt. Bei Klick auf einen Button werden alle diese Image Controls mit (verschiedenen) JPEGs gefüllt:


ImageControlName.Source = new BitmapImage(new Uri(@"E:\somepath\graphic.jpg", UriKind.RelativeOrAbsolute));

Bei Klick auf einen weiteren Button werden die Image-Controls mit anderen JPEGs gefüllt (gleicher Code, aber andere Pfade).

In beiden Schritten werden jeweils 30 Bilder à 1680x1050 Pixel geladen.

Nach Schritt 1 zeigt der Task Manager einen Verbrauch von 300MB an, nach dem zweiten Schritt sind es über 600.

Leider führt das zu langwierigen Swappen des Hauptspeicher-Inhaltes zwischen Platte und RAM. Ein Dispose oder ähnliches habe ich aber leider nicht gefunden. GC.Collect() bringt exakt gar nichts. Das Entladen der Form auch. Erst, wenn das Programm komplett beendet wird, wird der Speicher freigegeben. Wie bekomme ich meine Resourcen denn wieder frei?

Danke im Voraus,

Stefan

Gelöschter Account
vor 15 Jahren

zeigst du die bilder in voller bildgröße an? ansonsten kannst du auch ein thumbnail image erzeugen.

vbtricks Themenstarter:in
205 Beiträge seit 2006
vor 15 Jahren

Salut,

das verschiebt das Problem leider nur. Ich hatte dasselbe auch mit 60 Bildern nacheinander anzeigen probiert, mit demselben Ergebnis.
Das kann doch nicht sein, dass sich die WPF-Entwickler da nichts gedacht haben. Ich als Entwickler habe doch in vielen Fällen die besseren Informationen, wann ich Bilder nicht mehr brauche, da kann die eingebaute Vorhaltestrategie noch so gut sein...

Stefan

Gelöschter Account
vor 15 Jahren

was für ein control verwendest du?

vbtricks Themenstarter:in
205 Beiträge seit 2006
vor 15 Jahren

Salut,

ich verwende System.Windows.Controls.Image.

Bin jetzt ein Stückchen schlauer, wie die Caching-Strategie von WPF funktioniert. Ich hatte testweise die Bilder in einer Schleife dem Image-Control zugewiesen, da trat das Problem mit dem immensen Speicherverbrauch auf.

Bei normalem Durchklicken durch ein Photo-Album pendelt sich der Verbrauch bei ~50MB ein.

Das Verhalten lässt sich mit folgendem Programm nachvollziehen. Klickt man mit kurzer Pause auf den Button, so schwankt der Verbrauch um 50MB. Klickt man dagegen schnell in Folge auf den Button, kann man den Verbrauch drastisch in die Höhe treiben. Nach dem letzten Klick in der schnellen Folge wird aber nicht etwa aufgeräumt, sondern erst, nachdem ein weiteres Bild in etwas größerem Abstand geladen wurde.

Für mich im Endeffekt heißt das, dass ich die Bilder nacheinander in großer Größe mit den Standard-WPF-Methoden (siehe unten) anzeigen kann. Für die Leiste mit den Thumbnails greife ich auf den Windows.Drawing-Namespace zurück (laden, verkleinern, speichern auf Platte).

Damit ist der Thread erledigt. Danke.


<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="600" Width="800">
    <DockPanel>
        <Button Name="NextImageButton" Click="NextImageButton_Click" DockPanel.Dock="Top">Next image</Button>
        <Image Name="MyImage" />
    </DockPanel>
</Window>

    public partial class Window1 : Window
    {
        string[] files;
        int curImageindex = -1;

        public Window1()
        {
            InitializeComponent();

            this.files = System.IO.Directory.GetFiles(@"D:\Bilderpfad", "*.jpg");
        }

        private void NextImageButton_Click(object sender, RoutedEventArgs e)
        {
            curImageindex = (curImageindex + 1) % files.Length;
            this.MyImage.Source = new BitmapImage(new Uri(this.files[curImageindex], UriKind.Absolute));
        }
    }