Mam aplikację (WPF), która tworzy BitmapImages w wielkich liczbach (np. 25000). Wygląda na to, że framework wykorzystuje pewną wewnętrzną logikę, więc po utworzeniu jest około 300 MB zużytej pamięci (150 wirtualnych i 150 fizycznych). Te BitmapImages są dodawane do obiektu Image i są dodawane do Canvas. Problem polega na tym, że po zwolnieniu wszystkich tych obrazów pamięć nie jest zwalniana. Jak mogę odzyskać pamięć?Czyszczenie pamięci nie pozwala odzyskać BitmapImage?
Aplikacja jest prosta: Xaml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Canvas x:Name="canvas" Grid.ColumnSpan="2"></Canvas>
<Button Content="Add" Grid.Row="1" Click="Button_Click"/>
<Button Content="Remove" Grid.Row="1" Grid.Column="1" Click="Remove_click"/>
</Grid>
Code-za
const int size = 25000;
BitmapImage[] bimages = new BitmapImage[size];
private void Button_Click(object sender, RoutedEventArgs e)
{
var paths = Directory.GetFiles(@"C:\Images", "*.jpg");
for (int i = 0; i < size; i++)
{
bimages[i] = new BitmapImage(new Uri(paths[i % paths.Length]));
var image = new Image();
image.Source = bimages[i];
canvas.Children.Add(image);
Canvas.SetLeft(image, i*10);
Canvas.SetTop(image, i * 10);
}
}
private void Remove_click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < size; i++)
{
bimages[i] = null;
}
canvas.Children.Clear();
bimages = null;
GC.Collect();
GC.Collect();
GC.Collect();
}
To jest zrzut ekranu ResourceManager Po dodaniu zdjęć
"około 300 MB zużytej pamięci (150 wirtualnych i 150 fizycznych)", która jest całkowicie BOGUS. Czytaj w pamięci. – leppie
Nie należy używać GC.Collect(), ale Bitmap.Dispose(). –
Twoje wezwanie "GC" nic tam nie zrobi. Zakładając, że nie ma wybitnych odniesień do zrootowanych obiektów 'BitmapImage', CLR odzyska pamięć, kiedy będzie jej potrzebować. – MoonKnight