保存位图时内存泄漏?

时间:2011-06-20 20:48:14

标签: c# image memory-leaks bitmap

我正在计算机上保存当前图像的屏幕截图:

Rectangle bounds = Screen.GetBounds(Point.Empty);

using (var bitmap = new Bitmap(bounds.Width, bounds.Height))
{
    using (Graphics g = Graphics.FromImage(bitmap))
    {
       g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
    }

    using (var mss = new MemoryStream())
    {
        bitmap.Save(mss,ImageFormat.Gif);
    }
}

内存漏洞就在这段代码中:

bitmap.Save(mss,ImageFormat.Gif);

我不应该使用using处理我正在使用的所有内容吗?

为什么在拍摄大量照片时内存仍然非常高,并且内存未被释放?

谢谢!

2 个答案:

答案 0 :(得分:3)

当我问this question on SO.

时,您可能会遇到同样的问题

我的问题是,即使在MemoryStream上调用byte[]Dispose也未释放其内部byte[]。在MemoryStream超出范围并由GC收集之前,MemoryStream不会被释放。

This blog post详细说明问题的原因,并提供a working solution.它对我有用,我怀疑你遇到了同样的问题。本质上,它将底层Dispose()包装在一个实现相同接口的类型中,但在调用byte[]时将流引用设置为null。由于没有其他对象应该具有对内部流的实时引用,因此GC允许GC进入并清理它。

此外,由于内部{{1}}可能会在大对象堆上分配,导致多次分配后出现碎片,这个问题更加复杂。

答案 1 :(得分:2)

您可以尝试使用BufferManager,它将为您管理Byte []。

        // declare the BufferManager somewhere. Check thread safety!
        BufferManager bm = BufferManager.CreateBufferManager(qqq, yyy);


        // wrap your current code to use the buffer manager
        Rectangle bounds = Screen.GetBounds(Point.Empty);

        using (var bitmap = new Bitmap(bounds.Width, bounds.Height))
        {
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
            }

            byte[] buffer = bm.TakeBuffer(yyy);
            try
            {
              using (MemoryStream stream = new MemoryStream(buffer))
              {
                 bitmap.Save(mss,ImageFormat.Gif);
              }
            }
            finally
            {
               bm.ReturnBuffer(buffer);
            }
       }