gpt4 book ai didi

c# - 处理大图像时垃圾收集器太慢

转载 作者:行者123 更新时间:2023-11-30 20:20:48 25 4
gpt4 key购买 nike

我正在使用 Emgu OpenCV 从网络摄像头抓取图像,并希望使用 WPF Image 控件将它们可视化。
所以我需要将图像从 Mat 转换为与 Image 控件兼容的东西。所以我从 Emgu 示例中学习了这个类:

public static class BitmapSourceConvert
{
/// <summary>
/// Delete a GDI object
/// </summary>
/// <param name="o">The poniter to the GDI object to be deleted</param>
/// <returns></returns>
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);

/// <summary>
/// Convert an IImage to a WPF BitmapSource. The result can be used in the Set Property of Image.Source
/// </summary>
/// <param name="image">The Emgu CV Image</param>
/// <returns>The equivalent BitmapSource</returns>
public static BitmapSource ToBitmapSource(IImage image)
{
using (System.Drawing.Bitmap source = image.Bitmap)
{
IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
ptr,
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());

DeleteObject(ptr); //release the HBitmap
return bs;
}
}
}

这对于小图像(例如 640 x 480)来说非常有效。使用任务管理器时(我在 Windows 8 上),我看到使用的内存在增加和减少。工作正常。

但是当使用像 1920x1080 这样的大图像时,应用程序会在短时间后崩溃,并出现异常提示没有更多内存。再次查看任务管理器时,我可以看到内存消耗上升,一次下降然后上升,直到抛出异常。感觉垃圾收集器的工作频率不足以释放所有空间。

所以我尝试通过在函数中的某处添加 GC.Collect() 来手动启动垃圾收集器。它再次起作用。即使是大图像。

我认为手动调用垃圾收集器既不是好的风格也不是高效的。谁能提供有关如何在不调用 GC.Collect() 的情况下解决此问题的提示?

最佳答案

最后,我认为问题在于,垃圾收集器不知道图像有多大,因此无法规划合理的时间表。我找到了方法

GC.AddMemoryPreasure(long bytesAllocated)
GC.RemoveMemoryPreasure(long bytesAllocated)

这些方法告诉垃圾收集器何时分配和释放大型非托管对象,以便垃圾收集器可以更好地计划他的时间表。

下面的代码没有任何内存问题:

    public static BitmapSource ToBitmapSource(IImage image)
{
using (System.Drawing.Bitmap source = image.Bitmap)
{
IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap
long imageSize = image.Size.Height*image.Size.Width*4; // 4 bytes per pixel
GC.AddMemoryPressure(imageSize);
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
ptr,
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());

DeleteObject(ptr); //release the HBitmap
GC.RemoveMemoryPressure(imageSize);
return bs;
}
}

关于c# - 处理大图像时垃圾收集器太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35366247/

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