找不到内存泄漏

Mas*_*ief 9 c# memory memory-leaks image windows-phone-7

我一直在研究WP7应用程序,它的图像库应用程序,实现了基本的缩放和轻弹手势.

出于测试目的,我使用设置为Content的离线图像(它们的文件名已编号)编译应用程序,并通过硬编码字符串(稍后将替换)访问它们.

但后来意识到应用消耗了大量内存.我以为这是由于图像并发现了这个博客 ; 图像总是缓存.我使用博客中的代码来纠正这个问题.虽然消费率确实下降,但仍未释放内存.

为了最后的尝试,我创建了另一个带有基本功能2按钮的测试应用程序,用于图像的导航和图像控制,只是为了确保它不是我的手势代码可能是问题.

这是xaml

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Image Grid.Row="0" x:Name="ImageHolder" Height="Auto" Width="Auto" Stretch="Uniform" Tap="image_Tap" />
    <TextBlock x:Name="MemUsage" />
    <StackPanel Grid.Row="1" Orientation="Horizontal">
        <Button x:Name="PrevButton" Content="Prev" Width="240" Click="btnPrev_Click"/>
        <Button x:Name="NextButton" Content="Next" Width="240" Click="btnNext_Click"/>
    </StackPanel>
</Grid>
Run Code Online (Sandbox Code Playgroud)

这是.cs文件

    const int PAGE_COUNT = 42;
    int pageNum = 0;
    public MainPage()
    {
        InitializeComponent();
        RefreshImage();
    }

    private void btnPrev_Click(object sender, RoutedEventArgs e)
    {
        pageNum = (PAGE_COUNT + pageNum - 1) % PAGE_COUNT; // cycle to prev image
        RefreshImage();
    }

    private void btnNext_Click(object sender, RoutedEventArgs e)
    {
        pageNum = (PAGE_COUNT + pageNum + 1) % PAGE_COUNT; // cycle to next image
        RefreshImage();
    }

    private void image_Tap(object sender, GestureEventArgs e)
    {
        RefreshTextData();
    }

    private void RefreshImage()
    {
        BitmapImage image = ImageHolder.Source as BitmapImage;
        ImageHolder.Source = null;
        if (image != null)
        {
            image.UriSource = null;
            image = null;
        }
        ImageHolder.Source = new BitmapImage(new Uri("000\\image" + (pageNum + 1).ToString("D3") + ".jpg", UriKind.Relative));
        RefreshTextData();
    }

    private void RefreshTextData()
    {
        MemUsage.Text = "Device Total Memory = " + (long)DeviceExtendedProperties.GetValue("DeviceTotalMemory") / (1024 * 1024)
            + "\nCurrent Memory Usage = " + (long)DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage") / (1024 * 1024)
            + "\nPeak Memory Usage = " + (long)DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage") / (1024 * 1024);
    }
Run Code Online (Sandbox Code Playgroud)

但仍有内存泄漏,我无法指出它.我很难找到它.内存分析器显示我有很多字符串实例,我无法解释.

几点:

  • 我在"000"文件夹中有图像并命名为"image ###".目前我的图像文件名从"image001"到"image042"
  • 一旦完整显示第一页图像,测试应用程序的内存占用量为6 MB,在fisrt页面更改后,它上升到大约18-20 MB
  • 如果图像数量允许,后续页面更改会导致内存逐渐增加,然后最终崩溃,否则在循环浏览所有图像后内存消耗将保持不变
  • 我使用大约1280 x 2000的.jpg文件进行测试我没有调整图像大小.

堆摘要 - >新分配

Kev*_*sse 6

我有相同类型的应用程序,下一个/上一个图片按钮.我有完全相同的内存泄漏,这让我很生气.

我仍然无法找到根本原因,但我已经设法绕过它丑陋的黑客.当显示下一张图片时,我强制旧图像源加载无效图片,从而释放内存.我不明白为什么删除所有引用并调用垃圾收集器是不够的,必须在内部保留另一个引用.

无论如何,这是黑客:

private void DisposeImage(BitmapImage image)
{
    if (image != null)
    {
        try
        {
            using (var ms = new MemoryStream(new byte[] { 0x0 }))
            {
                image.SetSource(ms);
            }
        }
        catch (Exception)
        {
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以在你的RefreshImage方法中调用它:

private void RefreshImage()
{
    BitmapImage image = ImageHolder.Source as BitmapImage;
    ImageHolder.Source = null;

    DisposeImage(image);

    ImageHolder.Source = new BitmapImage(new Uri("000\\image" + (pageNum + 1).ToString("D3") + ".jpg", UriKind.Relative));
    RefreshTextData();
}
Run Code Online (Sandbox Code Playgroud)

有点惭愧使用它,但至少它似乎工作.