Speicherverbrauch von BitmapImage / Bildsteuerung in Windows Phone 8

Ich teste eine WP8-App und deren Bildbetrachter zeigt viele Bilder an. Ich habe festgestellt, dass der Speicherverbrauch der App steigt, und möchte herausfinden, wie er gelöst werden kann.

Ich habe einige Artikel aus dem Internet gelesen. Die in diesen Artikeln bereitgestellten Lösungen funktionieren jedoch nicht in meiner App. Bitte lesen Sie den Verlauf unten.

Zuerst fand ich den Artikel "Bildtipps für Windows Phone 7msgstr "" "und lade sein Beispiel herunter, um einen sauberen Bild - Cache zu testen, mit dem es arbeitet1 Bild.

Und dann zu Testzwecken mache ich diese App mit15 Offline-Bilder Laden Sie die Test-App in der App herunter und stellen Sie sie als "Inhalt" einHier.

Meine Testschritte sind:

(1) Launch app
(2) Go to Image Caching page
(3) Enable checkbox "Avoid Image Caching"
(4) Continuously tapping button Show/Clear
(5) Keep watching the memory status textblock at the bottom

Wenn ich meine App teste, steigt der Speicher wie16.02MB => Anzeigen (19,32 MB) => Löschen (16,15 MB) => Anzeigen (20,18 MB) => Löschen (17,03 MB) ... etc Und Speicher wird nicht freigegeben, selbst wenn die Cacheseite verlassen und erneut zur Cacheseite gewechselt wird. Es scheint die Lösung des Artikels "Bildtipps für Windows Phone 7"arbeitet nur für1 Bild.

Hier kommt die XAML und Code-Behind-Lösung von "Bildtipps für Windows Phone 7".

[Caching.xaml]

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
                <ToggleButton Content="Show" Width="150" Checked="ShowImageClicked" Unchecked="ClearImageClicked"/>
                <CheckBox x:Name="cbAvoidCache" Content="Avoid Image Caching"/>
            </StackPanel>
            <Image x:Name="img" Grid.Row="2" Width="256" Height="192"/>
            <TextBlock x:Name="tbMemory" Grid.Row="2" Text="Memory: " VerticalAlignment="Bottom" Style="{StaticResource PhoneTextLargeStyle}"/>
        </Grid>

[Caching.xaml.cs]

public partial class Caching : PhoneApplicationPage
{
    public Caching()
    {
        InitializeComponent();

        DispatcherTimer timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromMilliseconds(500);
        timer.Start();
        timer.Tick += delegate
        {
            GC.Collect();
            tbMemory.Text = string.Format("Memory: {0} bytes", DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage"));
        };
    }

    private int nIndex = 1;
    BitmapImage bitmapImageFromUri = new BitmapImage();
    private void ShowImageClicked(object sender, RoutedEventArgs e)
    {
        string strImage = string.Format("../ImagesAsContent/{0:D2}.jpg", nIndex);
        bitmapImageFromUri.UriSource = new Uri(strImage, UriKind.Relative);
        img.Source = bitmapImageFromUri;

        nIndex++;
        if (nIndex > 15)
        {
            nIndex = 1;
        }

        (sender as ToggleButton).Content = "Clear";
    }

    private void ClearImageClicked(object sender, RoutedEventArgs e)
    {
        if (cbAvoidCache.IsChecked == true)
        {
            // set the UriSource to null in order to delete the image cache
            BitmapImage bitmapImageFromUri = img.Source as BitmapImage;
            bitmapImageFromUri.UriSource = null;
        }
        img.Source = null;
        (sender as ToggleButton).Content = "Show";
    }
}

Ich habe auch versucht, nach anderen Lösungen zu suchen. Einige Testergebnisse sind unten aufgeführt.

1. Artikel[wpdev] Speicherverlust mit BitmapImage": Es bietet 2 Lösungen, eine ist die DisposeImage API, eine andere ist, die BitmapImage Quelle auf Null zu setzen, wie unten gezeigt. Auch in dem Artikel wird darauf hingewiesen, dass wir beim Anhängen / Entfernen von Ereignishandlern vorsichtig sein müssen, meine Test-App hat jedoch keine Ereignishandler in Caching-Seite.

[DisposeImage]

private void DisposeImage(BitmapImage image)
{
    if (image != null)
    {
        try
        {
            using (var ms = new MemoryStream(new byte[] { 0x0 }))
            {
                image.SetSource(ms);
            }
        }
        catch (Exception)
        {
        }
    }
}

[Null setzen]

BitmapImage bitmapImage = image.Source as BitmapImage;
bitmapImage.UriSource = null;
image.Source = null;

(2) Artikel "Windows Phone: Listbox mit nicht genügend Speicherplatz für Bilder": Es bietet eine API" DisposeImage "mit wenig Unterschied zu (1) wie unten, aber dies funktioniert auch nicht, ich habe immer noch das Symptom der Speichererhöhung.

public static void DisposeImage(BitmapImage image)
{
    Uri uri= new Uri("oneXone.png", UriKind.Relative);
    StreamResourceInfo sr=Application.GetResourceStream(uri);
    try
    {
     using (Stream stream=sr.Stream)
     {
      image.DecodePixelWidth=1; //This is essential!
      image.SetSource(stream);
     }
    }
    catch
    {}
}

3. ArtikelSpeicherleck nicht gefundenMsgstr ": Es werden die gleichen 2 Lösungen wie oben angegeben bereitgestellt. Außerdem wird erwähnt, dass das Problem nicht für Bilder von isolierten Speichern gelten kann. Die Bilder meiner Testanwendung stammen jedoch aus isolierten Speichern.

(4) Ich habe auch 1000 Bilder getestet. Das Testergebnis ist ein Absturz der App, wenn die App nacheinander etwa 190 Bilder anzeigt. Informationen zum Speicher finden Sie in der Windows Phone-Anwendungsanalyse.

Abschließend danke ich Ihnen für Ihre Geduld, meine Frage und Geschichte zu lesen, und arbeite seit vielen Tagen daran, eine Lösung zu finden. Wenn Sie eine Ahnung oder Lösung haben, lassen Sie es mich bitte wissen.

Vielen Dank.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage