用C#编写了一段代码,循环更新显示picturebox里的图片。但是程序在运行一段时间后就会报内存溢出错误,程序运行过程中内存增加非常快。代码如下:
public delegate void myinvoke(Image img); public static Image img; public void child() { while(true) { int h = 500; int w = 500; byte[] huidushuzu = new byte[500*500 * 3]; for (int k = 0; k < (500 * 500 * 3); k += 3) { double kk = (double)k; huidushuzu[k + 2] = huidushuzu[k + 1] = huidushuzu[k] = (byte)(((kk + 1.0) / (500.0 * 500.0 * 3.0)) * 255.0); } Bitmap mybmp = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb); //从创建的mybmp中锁定rect范围的像素,生成bitmapdata Rectangle rect = new Rectangle(0, 0, 500, 500); System.Drawing.Imaging.BitmapData bitmapData = mybmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, mybmp.PixelFormat); //得到首地址 IntPtr ptr = bitmapData.Scan0; int bytes = mybmp.Width * mybmp.Height * 3;//定义被锁定的数组大小 System.Runtime.InteropServices.Marshal.Copy(huidushuzu, 0, ptr, bytes);//把数组huidushuzu复制到位图内,0-起始位置,bytes-长度 mybmp.UnlockBits(bitmapData);//解锁像素 img = Image.FromHbitmap(mybmp.GetHbitmap()); myinvoke my = new myinvoke(dowork); this.BeginInvoke(my, new object[] { img }); } } public void dowork(Image img) { pictureBox1.Image = img; pictureBox1.Show(); }
后面又用了using、dispose、gc.collect等释放内存的方法,还是不能解决。
最后查了一下Image.FromHbitmap方法,发现:FromHbitmap方法会生成位图的副本 GDI 。
那么每循环一次就会生成一个副本,最后导致内存溢出。
解决方法:bitmap类是从image类继承的一个图像类,不用Image.FromHbitmap,直接把bitmap赋给image,即
将img = Image.FromHbitmap(mybmp.GetHbitmap());
改为img=mybmp;
修改完成后内存就会不溢出了。