【问题标题】:Image memory clean after i call GC.Collect() many time多次调用 GC.Collect() 后图像内存清理
【发布时间】:2019-01-23 10:59:17
【问题描述】:

我正在使用图像进行预览。在我工作之后,我只是将 ImageSource 设置为 null 并调用 GC.Collect() 但在调用 GC.Collect() 后 50% 内存仍处于保持状态,并且它保持到我再次调用 GC.Collect() ..

为什么需要我打电话来清理?

点击后销毁

private void ImgDistry_Click(object sender, RoutedEventArgs e)
    {
        image.Source = null;
        GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
    }

销毁图像后设置image.Source = null,并调用GC.Collect();记忆仍被搁置。它应该会在一段时间后自动清洁。

它会保留内存,直到我在 15-30 秒后调用 GC.Collect() 2-3 次。我怎样才能立即清理未使用的位图内存?

查看视频(里面的代码和步骤):- https://www.dropbox.com/s/457hhjnlttbzhlp/TinyTake%20by%20MangoApps-16-08-2018-06-28-51.mp4?dl=0

private void ImgDisplay_Click(object sender, RoutedEventArgs e)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        var bitmap = new BitmapImage();
        using (var stream = File.OpenRead(filePath))
        {
            bitmap.BeginInit();
            bitmap.CacheOption = BitmapCacheOption.OnLoad;
            bitmap.StreamSource = stream;
            bitmap.EndInit();
            bitmap.Freeze();
        }
        image.Source = bitmap;
    }

    private void ImgDistry_Click(object sender, RoutedEventArgs e)
    {
        image.Source = null;
        GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
    }

    private void ImgSelect_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog openFileDialog1 = new OpenFileDialog();
        openFileDialog1.ShowDialog();
        filePath = openFileDialog1.FileName;
    }

【问题讨论】:

  • 我不能(也不想)看你的视频。请详细解释预期和观察到的行为,以及您在观察期间采取的步骤。您是否可能正在使用调试器单步执行 ImgDistry_Click 中的代码,并想知道为什么在 Collect 之后没有立即释放内存?
  • @Clemens 是的,我的问题是为什么在 Collect 之后没有立即释放以及为什么它正在等待另一个 Collect 调用来释放内存..它应该立即或在一段时间后释放..
  • 可能是因为虽然您设置了image.Source = null,但BitmapImage 仍在使用中,因为Dispatcher 没有时间更新Image 元素。
  • @Clemens 好的,所以如果 Dispatcher 没有时间更新 Image 元素.. 所以它会一直保持,直到我再次调用正确?那么什么是立即释放内存或一段时间后自动释放的方法?
  • @Clemens 是 WPF 中的这个错误没有立即清理位图图像内存吗?

标签: c# wpf memory-leaks bitmapimage


【解决方案1】:

得到答案.. 设置 null 为图像源后需要更新布局然后调用 GC

private void ImgDistry_Click(object sender, RoutedEventArgs e)
    {
        image.Source = null;
        UpdateLayout();
        GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 1970-01-01
    • 2013-02-04
    相关资源
    最近更新 更多