6

我的应用程序在这行中出现内存泄漏。如果我查看任务管理器,每次触发此进程时,RAM 内存都会增加 +- 300 MB。

Bitmap bmp1 = new Bitmap(2480, 3508);
panel1.DrawToBitmap(bmp1, new Rectangle(0, 0, 2480, 3508));
pictureBox2.Image = bmp1;

有人可以帮我解决他的泄漏吗?如果我使用:

bmp1.Dispose();

我在这一行的“Program.cs”中遇到异常:在此Application.Run(new Form1()); 之后,应用程序停止运行......

屏幕应用: 在此处输入图像描述

4

4 回答 4

15

更新:您本身没有内存泄漏,您只需要等待垃圾收集器释放资源即可。

如果你确实想制作垃圾收集器collect,你可以这样做:

System.GC.Collect();
System.GC.WaitForPendingFinalizers();

为什么需要处理位图?如果您的 PictureBox 正在使用它,那么您需要位图。如果您要对其进行大量更改,也许您应该将旧位图换成新位图并丢弃旧位图:

Bitmap bmp1 = new Bitmap(2480, 3508);
panel1.DrawToBitmap(bmp1, new Rectangle(0, 0, 2480, 3508));
Image img = pictureBox1.Image;
pictureBox1.Image = bmp1;
if (img != null) img.Dispose(); // this may be null on the first iteration
于 2013-02-19T12:49:41.220 回答
4

我认为您应该只处理不再需要的图像。您仍然需要bmp1创建的,您只需将其设置为pictureBox2.Imagefield 的内容。尝试以下方式:

Bitmap bmp1 = new Bitmap(2480, 3508);
panel1.DrawToBitmap(bmp1, new Rectangle(0, 0, 2480, 3508));
Bitmap bmp2 = (Bitmap)pictureBox2.Image;
pictureBox2.Image = bmp1;
bmp2.Dispose();

免责声明:我没有 C# 经验,所以我可能错了......

于 2013-02-19T12:52:59.050 回答
1

您应该使用外部 gdi32.dll 来避免位图内存泄漏

[System.Runtime.InteropServices.DllImport("gdi32.dll")] 
public static extern bool DeleteObject(IntPtr hObject);
//your bitmap usage code here
...
//delete bitmap handle when you don't need the bitmap anymore
DeleteObject((IntPtr)hBitmap);
于 2019-03-26T18:07:34.680 回答
-1
    Bitmap copy_Screen()
    {
        try
        {
            var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
            var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
            try
            {
                gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
            }
            catch (Exception) { }
            return bmpScreenshot;
        }
        catch (Exception) { }
        return new Bitmap(10, 10, PixelFormat.Format32bppArgb);
    }

    private void button5_Click(object sender, EventArgs e)
    {
        //Start Stop timer
        if (timer1.Enabled == false) { timer1.Enabled = true; } else { timer1.Enabled = false; }
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        //memory leak solve
        System.GC.Collect();
        System.GC.WaitForPendingFinalizers();

        Bitmap BM = copy_Screen();
        if (pictureBox1.Image != null)
        {
            pictureBox1.Image.Dispose();
        }
        pictureBox1.Image = BM;

    }
于 2016-02-28T17:26:15.030 回答