C# 保存位图时是否会出现memoryleak?

C# 保存位图时是否会出现memoryleak?,c#,image,memory-leaks,bitmap,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.S

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

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);
    }
}
memoryleak位于以下代码处:

bitmap.Save(mss,ImageFormat.Gif);
我使用的
using
不应该处理我正在使用的所有东西吗

为什么在拍摄大量照片时,我的内存使用率仍然很高,而内存却没有释放出来


谢谢大家!

您可能看到的问题与我询问时遇到的问题相同

在我的例子中,问题是
MemoryStream
即使在调用
Dispose
时也没有释放其内部
byte[]
。直到
MemoryStream
超出范围并被GC收集,才会释放
字节[]

详细说明问题的原因,并说明它对我有效,我怀疑您遇到了相同的问题。本质上,它将底层的
MemoryStream
封装在一个实现相同接口的类型中,但在调用
Dispose()
时将流引用设置为null。由于没有其他对象应该具有对内部流的实时引用,因此允许GC突袭并清理它


此外,内部
字节[]
很可能会分配到大型对象堆上,这会导致多次分配后出现碎片。您可以尝试使用BufferManager,它会为您管理字节[]

        // 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);
            }
       }

我在读,你知道吗,在你的情况下你用了整个班级吗?是的,我用了整个班级。我不知道你怎么能少拿一点。它继承自抽象的
类,因此您必须实现所有这些方法,这就是允许它被视为流的原因,即使所有实际工作都被传递下来。所以我将当前memorystream放在新的wrappedstream中,对吗?使用(WrappingStream wp=newwrappingstream(mss))尝试一下,就像那样。另外,如果你还没有准备好,我建议你使用一个分析器。这个产品非常棒,他们有14天的试用期(我不为他们工作,就像产品一样:)。你确定吗?此时,您需要通过探查器运行应用程序并返回结果。在您这样做之前,我们只是猜测。根本问题是:为什么您需要将位图存储到内存流中?为什么不只存储新字节[]?为什么是BufferManager?它将1)返回长度为1米、2米、4米、8米、16米等的缓冲区(我假设缓冲区也小于1米,但没有验证),因此如果您要求9米,您将得到16米阵列。2) 缓冲区管理器永远不会自行清理,因此您必须手动调用BufferManager.clean()。另见和