将 Tiff 帧加载到动态创建的 Wpf Image 控件中时发生内存泄漏
Memory leak when loading Tiff frames into dynamically created Wpf Image controls
在将 tif 帧加载到动态创建的图像控件中时,我有一个巨大的内存使用进度,这是逻辑,
但是当我删除我的图像控件时,使用过的内存不会卸载!这就是我不明白的。
这是我的测试代码:
XAML:
<Grid>
<Button Content="Load" Margin="0,0,582,280" Click="OnLoadClck"/>
<ScrollViewer Margin="10,54,0,0" HorizontalScrollBarVisibility="Visible">
<StackPanel Orientation="Horizontal" x:Name="panel">
</StackPanel>
</ScrollViewer>
<Button Content="Unload" Margin="147,0,435,280" Click="OnUnloadClick"/>
</Grid>
后台代码:
private void OnLoadClck(object sender, RoutedEventArgs e)
{
TiffBitmapDecoder tbd = new TiffBitmapDecoder(new Uri("d:\test.tif"), BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnDemand);
for (int i = 0; i < tbd.Frames.Count; i++)
{
var f = tbd.Frames[i];
Image img = new Image{Width=100, Height=150 };
img.Source = f;
panel.Children.Add(img);
}
}
private void OnUnloadClick(object sender, RoutedEventArgs e)
{
while(panel.Children.Count>0)
{
Image img = panel.Children[0] as Image;
img.Source = null;
panel.Children.Remove(img);
}
}
我认为我的控件卸载任务很糟糕,但我不知道如何以正确的方式完成它。
感谢您的帮助。
我检查了您的示例应用程序,没有发现任何内存泄漏。我使用了来自 here 的 24 位 lzw 压缩 tiff 图像。对象在垃圾收集后按预期释放。我添加了第三个按钮,让 GarbageCollection 立即发生:GC.Collect();
结果如下:http://www.screencast.com/t/F5hhyTkAQ3e
当您添加图像时,它们会被添加到内存中。当您单击卸载时,您将删除对它们的任何引用,但这并不意味着垃圾收集将立即开始。对象被放入大对象堆和垃圾收集中,发生速度不如第一代对象。
但是当GC完成后(比如你可以在unload之后点击add,这样可能会forse GC),对象就成功的从内存中移除了。
在将 tif 帧加载到动态创建的图像控件中时,我有一个巨大的内存使用进度,这是逻辑, 但是当我删除我的图像控件时,使用过的内存不会卸载!这就是我不明白的。 这是我的测试代码: XAML:
<Grid>
<Button Content="Load" Margin="0,0,582,280" Click="OnLoadClck"/>
<ScrollViewer Margin="10,54,0,0" HorizontalScrollBarVisibility="Visible">
<StackPanel Orientation="Horizontal" x:Name="panel">
</StackPanel>
</ScrollViewer>
<Button Content="Unload" Margin="147,0,435,280" Click="OnUnloadClick"/>
</Grid>
后台代码:
private void OnLoadClck(object sender, RoutedEventArgs e)
{
TiffBitmapDecoder tbd = new TiffBitmapDecoder(new Uri("d:\test.tif"), BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnDemand);
for (int i = 0; i < tbd.Frames.Count; i++)
{
var f = tbd.Frames[i];
Image img = new Image{Width=100, Height=150 };
img.Source = f;
panel.Children.Add(img);
}
}
private void OnUnloadClick(object sender, RoutedEventArgs e)
{
while(panel.Children.Count>0)
{
Image img = panel.Children[0] as Image;
img.Source = null;
panel.Children.Remove(img);
}
}
我认为我的控件卸载任务很糟糕,但我不知道如何以正确的方式完成它。 感谢您的帮助。
我检查了您的示例应用程序,没有发现任何内存泄漏。我使用了来自 here 的 24 位 lzw 压缩 tiff 图像。对象在垃圾收集后按预期释放。我添加了第三个按钮,让 GarbageCollection 立即发生:GC.Collect();
结果如下:http://www.screencast.com/t/F5hhyTkAQ3e
当您添加图像时,它们会被添加到内存中。当您单击卸载时,您将删除对它们的任何引用,但这并不意味着垃圾收集将立即开始。对象被放入大对象堆和垃圾收集中,发生速度不如第一代对象。 但是当GC完成后(比如你可以在unload之后点击add,这样可能会forse GC),对象就成功的从内存中移除了。