Sto testando un'app WP8 e il suo visualizzatore di immagini per mostrare molte immagini, ho scoperto che il consumo di memoria delle app sta aumentando e voglio scoprire come risolverlo.Consumo di memoria di BitmapImmagine/Controllo immagine in Windows Phone 8
Ho letto alcuni articoli dal web, tuttavia le soluzioni fornite da tali articoli non funzionano sulla mia app, si prega di leggere la cronologia qui sotto.
Innanzitutto, ho trovato l'articolo "Image Tips for Windows Phone 7" e scaricato il suo esempio per eseguire il test della cache delle immagini, funziona con 1 immagine.
E poi a scopo di test, io faccio questo app compilato con 15 immagini non in linea all'interno della app, e impostata come "Contenuto", si prega di scaricare test di app dalla here.
miei passi di prova sono:
(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
quando sto testando la mia app, la memoria sta sollevando, come 16.02MB => Show (19.32MB) => Cancella (16.15MB) => Mostra (20.18MB) => Cancella (17.03MB) ... ecc. E la memoria non verrà liberata anche lasciando la pagina di memorizzazione nella cache e tornando alla pagina di memorizzazione nella cache. Sembra che la soluzione dell'articolo "Image Tips for Windows Phone 7" funzioni solo per 1 immagine.
Ecco l'xaml e il code-behind della soluzione di "Image Tips for 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";
}
}
Ho anche provato a cercare altre soluzioni, alcuni risultati dei test sono le seguenti.
(1) Articolo "[wpdev] Memory leak with BitmapImage": Fornisce 2 soluzioni, una è API DisposeImage, un'altra è quella di impostare l'origine BitmapImage su null come di seguito. Anche l'articolo ci fa sapere che dobbiamo stare attenti al gestore di eventi attach/dettach, tuttavia la mia app di test non ha un gestore di eventi nella pagina di cache.
[DisposeImage]
private void DisposeImage(BitmapImage image)
{
if (image != null)
{
try
{
using (var ms = new MemoryStream(new byte[] { 0x0 }))
{
image.SetSource(ms);
}
}
catch (Exception)
{
}
}
}
[Set null]
BitmapImage bitmapImage = image.Source as BitmapImage;
bitmapImage.UriSource = null;
image.Source = null;
(2) L'articolo "Windows phone: listbox with images out-of-memory": Fornisce un'API "DisposeImage" con poca differenza di (1 come di seguito, ma anche questo non funziona, ho ancora il problema di memoria.
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) L'articolo "Cannot find the memory leak": fornisce le stesse 2 soluzioni come sopra accennato, anche menzionato il problema non può repro per le immagini di archiviazione isolata, tuttavia le immagini il mio test di app sono da archiviazione isolata.
(4) Ho provato anche per 1000 immagini, il risultato del test è l'arresto anomalo dell'applicazione quando l'app mostrava circa 190 immagini in sequenza, fare riferimento alla grafica di analisi dell'applicazione Windows Phone per la memoria di seguito.
Infine, grazie per la vostra pazienza di leggere la mia domanda e la storia, ho lavorato su questo per trovare la soluzione per molti giorni. Se avete qualche indizio o soluzione, vi preghiamo gentilmente di farmelo sapere.
Grazie.
Buona domanda, hanno gli stessi problemi. Qualche notizia qui? –
Anche in cerca di una soluzione. Appare evidente che si tratta di un bug WP7.5, il che significa che si verifica anche su WP8 se non si seleziona solo il WP8. –