gpt4 book ai didi

c# - 使用 WriteableBitmap.AddDirtyRect() 时内存泄漏的解决方法

转载 作者:太空宇宙 更新时间:2023-11-03 10:42:09 25 4
gpt4 key购买 nike

当直接写入后备缓冲区并在单个锁定/解锁中多次使用 AddDirtyRect 函数时,WriteableBitmaps 似乎存在内存泄漏。矩形需要在位图中定义不同的区域。当您尝试丢弃 WriteableBitmap 时,内存将泄漏。

您可以通过将以下代码插入新的 WPF 应用程序来重新创建它。当应用程序启动时,调整窗口大小以创建新的 WriteableBitmaps 并观察内存增加。

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();

Image m = new Image();
m.Stretch = Stretch.Fill;
this.Content = m;

this.SizeChanged += OnSizeChanged;
}

private void OnSizeChanged(object sender, SizeChangedEventArgs args)
{
WriteableBitmap bm = new WriteableBitmap((int)args.NewSize.Width, (int)args.NewSize.Height, 96, 96, PixelFormats.Bgra32, null);

bm.Lock();
bm.AddDirtyRect(new Int32Rect(1, 1, 1, 1));
bm.AddDirtyRect(new Int32Rect(2, 2, 1, 1));
bm.Unlock();

((Image)this.Content).Source = bm;
}
}

我们需要能够丢弃位图,所以保留相同的位图并重复使用它不是一种选择。我们也不能直接写入后台缓冲区,而是使用 WritableBitmap.WritePixels(),但速度较慢且速度是个问题。

更新:我已经测试了 WritePixels 方法,它仍然会泄漏。可能是在不同区域调用太多写入太快的问题。

最佳答案

我们已就此问题联系了 Microsoft,这似乎是支持 WPF 的底层 C++ 库存在问题。我们没有得到何时(或是否)修复的 promise ,但它仍然是 .NET 4.5.1 的错误。

目前我们发现只有两种方法可以解决这个问题,而且它们相互排斥。您可以:

永远不会弄脏位图的任何子区域,只​​会弄脏整个位图

这种方法的问题是性能。您可以尝试通过缩小位图来抵消这种情况,但在很多情况下这是不可能的。

永远不要丢弃你的位图

如果您要弄脏位图的多个子部分,那么您必须确保它永远不会被垃圾回收,除非您要关闭应用程序。这带来了它自己的许多问题,因为您必须确保位图在第一次创建时足够大。如果允许用户调整窗口大小,那么您必须使其适合整个桌面,但即使这样也是有问题的,因为用户可以更改他们的桌面分辨率或添加/删除显示器,这意味着您要么必须泄漏内存,要么不泄漏内存足够的位图来覆盖整个可能的窗口大小。

希望 Microsoft 将来会为此发布修复程序,但同时要非常小心使用 WriteableBitmap,因为它很容易泄漏内存。

关于c# - 使用 WriteableBitmap.AddDirtyRect() 时内存泄漏的解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24960650/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com