C#中PictureBox的内存释放问题
-
11-09-2019 - |
题
我在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();
结果
现在,您可以删除,移动,或任何你想要的文件。