无法找到内存泄漏无法找到内存泄漏(Cannot find the memory leak)

2019-05-12 03:00发布

我一直在WP7的应用程序,它的形象画廊的应用程序,基本变焦和快速滑动手势的实现。

为了测试我编译离线图像应用程序(其文件名的编号)设置为内容,并通过硬编码字符串(稍后将代替)访问它们。

但感悟到应用占用了大量的内存。 我认为这是由于图像,发现这个博客 ; 图像总是缓存。 我使用的代码从博客进行整治。 仍然不会释放内存,虽然消费率没有下降。

对于最后一次尝试,我创建与导航及图像的图像控制基本特征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>

这是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);
    }

但还是内存泄漏是存在的,我不能针点它。 我有一个很难找到它。 存储器剖析表明,我有一个字符串的许多情况下,我无法解释。

几个要点:

  • 我有图片文件夹中的“000”,并命名为“图像###”。 目前我已经从“image001”与文件名图像“image042”
  • 测试应用程序,尽快拥有6 MB的内存占用,因为它显示的第一页完全与图像,并经过最前一页页改变它上升到几乎18-20 MB
  • 随后的页面变化导致内存逐渐增加,然后最终崩溃,如果图像的数量允许,通过所有图片循环后否则内存消耗是恒定的
  • 我使用.jpg文件与约维1280 * 2000,用于测试我不调整图像大小。

Answer 1:

我有同样的应用程序,下/上一张图片按钮。 和我一模一样的内存泄漏,这让我想疯了。

我还没有能够找到问题的根源,但我已经成功了丑陋的黑客绕过它。 当显示下一个画面,我迫使老图像源装载无效图像,从而释放所述存储器。 我不明白为什么删除所有引用和调用垃圾回收器是不够的,必须有另一种参考内部保持地方。

不管怎么说,这是黑客:

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

您可以在调用它例如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();
}

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



Answer 2:

我曾尝试你的代码示例,但在Windows Phone 8的环境下,我无法重现泄漏。 唯一的区别是,我用我自己的形象。

当前内存使用量停留在13MB我512 WVGA模拟器及山顶停留在14MB。 我已经推“下一个按钮,” 20倍左右。

也有你尝试使用绑定imageHolder的原因,而不是手动设置的来源?

(顺便说一句,在视觉上我没有看到你的代码隐藏任何可能的内存泄漏)。

(同时检查本文http://blogs.windows.com/windows_phone/b/wpdev/archive/2012/02/01/memory-profiling-for-application-performance.aspx )



Answer 3:

许多试运行和调试会话后,我发现,不执行此缓存图像(或没有积极进行)时,图像驻留在应用程序的IsolatedStorage。

事情是我用这是XAP文件的一部分的图像,包括为内容。 我这样做是因为我只是想测试我的图像浏览器。 但是,这不会是当我的应用程序将完成的情况。 应用程序是真正设计用于存储图像的独立存储并显示出来。

所以我设置必要的代码,并收集瞧,图片现在得到的垃圾,即使他们仍然有缓存。 见下文(见垃圾收集器被调用多少次)图像。 这是一个不能算小问题的解决方案,这就是为什么没有人遇到这样那样的问题。

我相信,当WP7的Silverlight发现图片是不是来自独立存储它假定图像是从一些偏僻的URI,并决定无论如何缓存它。 而这也正是Silverlight的图像缓存问题踢。作为另一个答案证实了这一点并没有发生在WP8。



Answer 4:

试试这个办法: 图片下载,支持自动记忆清洗 。 它是先进的KooKiZ的样品,它支持可视化。 示例项目是在这里: https://simca.codeplex.com/



文章来源: Cannot find the memory leak