我在C#中的纽比。我要反复刷新GUI图片框在一个工作线程。该图像从摄像机轮询与retrives要显示的图像的的getImage方法的驱动器获得的。即使我使用指示分配位图“使用”,并明确调用G.C,记忆似乎永远不会释放。

在工作线程是这样的:

   while (true)
    {
        // request image with IR signal values (array of UInt16)
        image = axLVCam.GetImage(0);
        lut = axLVCam.GetLUT(1);
        DrawPicture(image, lut);
        //GC.Collect();

    }

虽然DrawPicture方法是一样的东西

   public void DrawPicture(object image, object lut)
{

  [...]

    // We have an image - cast it to proper type
    System.UInt16[,] im = image as System.UInt16[,];
    float[] lutTempConversion = lut as float[];

    int lngWidthIrImage = im.GetLength(0);
    int lngHeightIrImage = im.GetLength(1);

    using (Bitmap bmp = new Bitmap(lngWidthIrImage, lngHeightIrImage)) {

      [...many operation on bitmap pixel...]

        // Bitmap is ready - update image control

        //SetControlPropertyThreadSafe(tempTxtBox, "Text", string.Format("{0:0.#}", lutTempConversion[im[160, 100]]));

        //tempTxtBox.Text = string.Format("{0:00000}", im[160, 100]);
        //System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
        pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
    }
}

问题出现与

  

pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());

在事实上评论该代码行,垃圾收集工作,它会。 更好,这个问题似乎是与

  

System.Drawing.Image.FromHbitmap(bmp.GetHbitmap())

任何建议来解决这个内存泄漏?

非常感谢!

有帮助吗?

解决方案

Image实现IDisposable,所以你应该调用每个Dispose实例创建Image,当不再需要它。你可以尝试在你的代码替换该行:

pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());

通过这样的:

if (pic.Image != null)
{
    pic.Image.Dispose();
}
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());

此将新的一个被分配之前处置先前图像(如果有的话)。

其他提示

的事情是,你正在做bmp的GDI位图GetHbitmap,它根据MSDN:

  

您是负责调用   GDI DeleteObject的方法来释放   存储器由GDI位图对象使用。

然后FromHbitmap方法使GDI位图的副本;这样你就可以创建新的图像之后立即释放使用GDI DeleteObject的方法传入GDI位图。

因此,基本上我要补充:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

...

IntPtr gdiBitmap = bmp.GetHbitmap();

// Release the copied GDI bitmap
if (pic.Image != null)
{
    pic.Image.Dispose();
}

pic.Image = System.Drawing.Image.FromHbitmap(gdiBitmap);

// Release the current GDI bitmap
DeleteObject(gdiBitmap);

我不确定,如果你需要的GDI的位图进行某种变换。如果你没有,你可以只是位分配给你的图片框的Image属性,而忽视了前者的解决方案:

// Since we're not using unmanaged resources anymore, explicitly disposing 
// the Image only results in more immediate garbage collection, there wouldn't 
// actually be a memory leak if you forget to dispose.
if (pic.Image != null)
{
    pic.Image.Dispose();
}

pic.Image = bmp;

有几种方法可以从PBOX释放的图像。我强烈推荐的方法是不使用pbox.Image = Image.FromFile...。如果你不使用的FileStream,你想从文件中使用Bitmap类阅读。像这样:

Bitmap bmp = new Bitmap(fileName);
pbox.Image = bmp; // notice that we used bitmap class to initialize pbox.

...然后你要释放的图像文件bmp.Dispose();结果 现在,您可以删除,移动,或任何你想要的文件。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top