不断创建位图会导致内存泄漏。

8

我有一个线程,不断生成位图并截取另一个程序窗口的屏幕截图。现在,我在我的窗体上有一个pictureBox,它不断地使用生成的位图更新。这是我在线程中的代码:

        Bitmap bitmap = null;

        while (true)
        {
            if (listBoxIndex != -1)
            {
                Rectangle rect = windowRects[listBoxIndex];
                bitmap = new Bitmap(rect.Width, rect.Height);
                Graphics g = Graphics.FromImage(bitmap);
                IntPtr hdc = g.GetHdc();
                PrintWindow(windows[listBoxIndex], hdc, 0);
                pictureBox1.Image = bitmap;
                g.ReleaseHdc(hdc);
            }
        }

正如您所见,由于对new Bitmap(rect.Width, rect.Height)的不断调用,这导致了内存泄漏。我尝试在while循环底部添加"bitmap.Dispose()",但这会导致pictureBox的图像也被释放,从而在实际图像位置上产生一个巨大的红色X。有没有办法在不释放pictureBox图像的情况下处理"bitmap"?

2个回答

10

你还在“泄漏”Graphics对象。试试这个:

    while (true)
    {
        if (listBoxIndex != -1)
        {
            Rectangle rect = windowRects[listBoxIndex];
            Bitmap bitmap = new Bitmap(rect.Width, rect.Height);
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                IntPtr hdc = g.GetHdc();
                try
                {
                    PrintWindow(windows[listBoxIndex], hdc, 0);
                }
                finally
                {
                    g.ReleaseHdc(hdc);
                }
            }
            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
            }
            pictureBox1.Image = bitmap;
        }
    }

哦,对了。怎么会忘记using关键字呢?我已经修改了我的代码。谢谢! - user1440308
使用位图将在分配给您的PictureBox后对其进行处理,这就是导致位图首先变得无法访问的原因。您需要在PictureBox上显示期间保持位图处于活动状态。 - Lucero
@xmenW.K. 到底哪里不对呢?Image.Dispose() 会释放本地图像指针,您可以自行查看源代码。 - Lucero
抱歉,我忘记删除那个注释了。 ;) - xmen
在我的情况下,Bitmap.Dispose()using Graphics g = Graphics.FromImage(Bitmap) 消除了内存泄漏。你能说一下为什么在将 Graphics g 声明为类成员并像这样实例化它 g = Graphics.FromImage(Bitmap); g.Dispose() 时不会释放内存吗? - EpiGen

1

在使用g.ReleaseHdc(..);后,该示例存在Graphics g泄漏的问题。

记得释放graphics变量。

例如:

g.Dispose();

这不对。他正在处理,"g"在一个"using"部分中,最终会自动调用"dispose"。 - ephraim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接