c# windows-phone-8 out-of-memory bitmapimage

c# - Consumo de memoria del control BitmapImage/Image en Windows Phone 8



windows-phone-8 out-of-memory (1)

Estaba lidiando con el mismo problema y, al final, creo que encontré una solución, no soy un programador profesional, pero esta es mi solución:

public Task ReleaseSingleImageMemoryTask(MyImage myImage, object control) { Pivot myPivot = control as Pivot; Task t = Task.Factory.StartNew(() => { Deployment.Current.Dispatcher.BeginInvoke(() => { if (myImage.img.UriSource != null) { myImage.img.UriSource = null; DisposeImage(myImage.img); } PivotItem it = (PivotItem)(myPivot.ItemContainerGenerator.ContainerFromIndex(myImage.number % 10)); Image img = FindFirstElementInVisualTree<Image>(it); if (img != null) { img.Source = null; GC.Collect(); } }); myImage.released = true; }); return t; } private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject { var count = VisualTreeHelper.GetChildrenCount(parentElement); if (count == 0) return null; for (int i = 0; i < count; i++) { var child = VisualTreeHelper.GetChild(parentElement, i); if (child != null && child is T) { return (T)child; } else { var result = FindFirstElementInVisualTree<T>(child); if (result != null) return result; } } return null; } private void DisposeImage(BitmapImage img) { if (img != null) { try { using (var ms = new MemoryStream(new byte[] { 0x0 })) { img = new BitmapImage(); img.SetSource(ms); } } catch (Exception e) { System.Diagnostics.Debug.WriteLine("ImageDispose FAILED " + e.Message); } } }

Espero que esto ayude :)

Estoy probando una aplicación WP8 y su visor de imágenes muestra muchas imágenes, el consumo de memoria de la aplicación está aumentando y quiero saber cómo solucionarlo.

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 " Sugerencias de imagen para Windows Phone 7 " y descargué su muestra para realizar pruebas limpias de caché de imágenes, está trabajando con 1 imagen .

Y luego, para fines de prueba, hago esta aplicación compilada con 15 imágenes fuera de línea dentro de la aplicación y configurada como "Contenido", descargue la aplicación de prueba desde aquí .

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, como 16.02MB => Mostrar (19.32MB) => Borrar ( 16.15MB ) => Mostrar (20.18MB) => Borrar ( 17.03MB ) ... etc Y la memoria no se liberará incluso dejando la página de almacenamiento en caché y volver a la página de almacenamiento en caché. Parece que la solución del artículo " Consejos sobre imágenes para Windows Phone 7 " funciona solo para 1 imagen .

Aquí viene la solución xaml y code-behind de " 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 cualquier otra solución, algunos resultados de prueba son los siguientes.

(1) Artículo " [wpdev] Fuga de memoria con BitmapImage ": Proporciona 2 soluciones, una es la API DisposeImage, otra es para establecer la fuente BitmapImage en nulo como se muestra a continuación. Además, el artículo nos indica que debemos tener cuidado con el controlador de eventos attach / dettach, sin embargo, mi aplicación de prueba no tiene controlador de eventos 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: listbox with images out-of-memory ": Proporciona una API "DisposeImage" con poca diferencia que (1) como la siguiente, pero esto tampoco funciona, todavía tengo la memoria elevando el síntoma

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 mencionadas anteriormente, también mencionó que el problema no puede reproducirse para imágenes de almacenamiento aisladas, 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 la falla de la aplicación cuando la aplicación mostró alrededor de 190 imágenes de forma secuencial; consulte la gráfica de análisis de aplicaciones de Windows Phone para ver la memoria a continuación.

Finalmente, gracias por su paciencia para leer mi pregunta e historial, he estado trabajando en esto para encontrar una solución durante muchos días. Si tiene alguna pista o solución, hágamelo saber.

Gracias.