image.fromhbitmap引起的内存溢出错误System.OutOfMemoryException

用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;

修改完成后内存就会不溢出了。

原文地址:https://www.cnblogs.com/winterbear/p/13638022.html