pic*_*cio 9 c# memory-leaks memory-management 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();
}
Run Code Online (Sandbox Code Playgroud)
虽然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());
}
}
Run Code Online (Sandbox Code Playgroud)
问题出现了
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
事实上,评论那行代码,垃圾收集工作就像它一样.更好的是,问题似乎与之相关
System.Drawing.Image.FromHbitmap(bmp.GetHbitmap())
有什么建议解决这个内存泄漏?
非常感谢!
Fre*_*örk 15
Image实现IDisposable,因此您应该Dispose在Image不再需要时调用您创建的每个实例.您可以尝试在代码中替换此行:
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
Run Code Online (Sandbox Code Playgroud)
有了这个:
if (pic.Image != null)
{
pic.Image.Dispose();
}
pic.Image = System.Drawing.Image.FromHbitmap(bmp.GetHbitmap());
Run Code Online (Sandbox Code Playgroud)
这将在分配新图像之前处理先前的图像(如果有的话).
问题是,你正在bmp使用GetHbitmap 创建一个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);
Run Code Online (Sandbox Code Playgroud)
我不确定你是否需要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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18778 次 |
| 最近记录: |