Consumo de memoria de BitmapImage / Image control en Windows Phone 8
Estoy probando una aplicación WP8 y el visualizador de imágenes muestra muchas imágenes. Descubrí que el consumo de memoria de la aplicación está aumentando y quiero saber cómo resolverlo.
He leído algunos artículos de la web, sin embargo, las soluciones proporcionadas por esos artículos no funcionan en mi aplicación, lea el historial a continuación.
Primero, encontré el artículo "Consejos de imagen para Windows Phone 7"y descargue su muestra para realizar pruebas de caché de imágenes limpias, está trabajando con1 imagen.
Y luego, para propósitos de prueba, hago esta aplicación compilada con15 imágenes sin conexión dentro de la aplicación, y establecer como "Contenido", descargue la aplicación de prueba deaquí.
Mis pasos de prueba son:
(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
Cuando estoy probando mi aplicación, la memoria está aumentando, como16.02MB => Mostrar (19.32MB) => Borrar (16.15MB) => Mostrar (20.18MB) => Borrar (17.03MB) ... etc. Y la memoria no se liberará ni siquiera dejando la página de almacenamiento en caché e ir a la página de almacenamiento en caché nuevamente. Parece la solución del artículo "Consejos de imagen para Windows Phone 7"está trabajando por sólo1 imagen.
Aquí viene el xaml y el código subyacente de la solución por "Consejos de imagen para 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";
}
}
También traté de buscar otras soluciones, algunos de los resultados de las pruebas son los siguientes.
(1) Artículo "[wpdev] Fuga de memoria con BitmapImage": Proporciona 2 soluciones, una es la API DisposeImage, otra es establecer el origen de BitmapImage en nulo como se muestra a continuación. Además, el artículo nos dice que debemos tener cuidado con el controlador / evento adjuntar / dettach, sin embargo mi aplicación de prueba no tiene controlador en la página de caché.
[DisposeImage]
private void DisposeImage(BitmapImage image)
{
if (image != null)
{
try
{
using (var ms = new MemoryStream(new byte[] { 0x0 }))
{
image.SetSource(ms);
}
}
catch (Exception)
{
}
}
}
[Establecer nulo]
BitmapImage bitmapImage = image.Source as BitmapImage;
bitmapImage.UriSource = null;
image.Source = null;
(2) Artículo "Windows Phone: cuadro de lista con imágenes fuera de memoria": Proporciona una API" DisposeImage "con poca diferencia a la de (1) como se muestra a continuación, pero esto tampoco funciona, todavía tengo el síntoma de aumento de 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) Artículo "No se puede encontrar la pérdida de memoria": Proporciona las mismas 2 soluciones que se mencionaron anteriormente, también mencionó que el problema no puede reproducirse para imágenes de almacenamiento aislado, sin embargo, las imágenes de mi aplicación de prueba son de almacenamiento aislado.
(4) También probé para 1000 imágenes, el resultado de la prueba es un bloqueo de la aplicación cuando la aplicación mostraba alrededor de 190 imágenes de forma secuencial, consulte los Gráficos de análisis de aplicaciones de Windows Phone para conocer la memoria a continuación.
Finalmente, gracias por su paciencia para leer mi pregunta y mi historia, he estado trabajando en esto para encontrar una solución durante muchos días. Si tiene alguna pista o solución, por favor hágamelo saber.
Gracias.