c#picturebox内存释放问题

我是C#的新手。 我必须在工作线程中重复刷新GUI图片框。 从使用GetImage方法轮询驱动程序的相机获取图像,该方法检索要显示的图像。 即使我使用指令“using”分配位图并显式调用GC,内存似乎永远不会被释放。

工作线程是这样的:

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 ,因此您应该在不再需要的每个Image实例上调用Dispose 。 您可以尝试在代码中替换此行:

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

有了这个:

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

这将在分配新图像之前处理先前的图像(如果有的话)。

问题是,你正在用GetHbitmap制作一个bmp的GDI位图,根据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位图来执行某种转换。 如果不这样做,您只需将位图分配给PictureBox的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();
现在您可以删除,移动或任何您想要的文件。