gpt4 book ai didi

c# - 当我不将 .Save() 的位图 .Dispose() 到 MemoryStream 时,为什么会发生内存泄漏?

转载 作者:行者123 更新时间:2023-11-30 14:15:54 27 4
gpt4 key购买 nike

假设我创建了一个位图

Bitmap bitmap = new Bitmap(320, 200);

当我将它写入某个流时(在我的例子中,它是一个 HttpResponseStream,由 HttpListenerResponse 给出),一切都很好:

bitmap.Save(stream, ImageFormat.Png);

我不需要 bitmap.Dispose(),位图使用的资源会自动清理。然而,直接将 Png 写入不可搜索流的问题在于它可能会导致 A generic error occurred in GDI+。 ,当我在 Azure 上试用我的 Asp 应用程序时,这发生在我身上。这就是我的代码现在的样子:

using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, ImageFormat.Png);
ms.WriteTo(stream);
}

现在除非我之后使用 bitmap.Dispose(),否则这会泄漏。

改写问题以获得更具体的答案:为什么这种位图内存泄漏似乎取决于我将其保存到哪种类型的流?

更新:正如我在评论中被问及是否确定这是泄漏一样。在压力测试中反复调用上述方法,我的 w3wp 进程将使用大量的内存,直到我的机器开始交换并且它不会清理。

最佳答案

位图类使用非托管资源。这些资源与内存流类使用的资源无关。您可以将位图类包装在一个 using 语句中,以便在您使用完位图实例后对其进行处理。

错过了您问题的后半部分。 “设置它并忘记它”的一种方法是创建一个包装类,它公开位图实例但实现一个处理位图实例的析构函数。这个析构函数意味着位图类在垃圾回收时被隐式处理。

作为最后的说明:您实例化的任何实现 IDisposable 的对象都必须由您的代码处理。 Dipose 永远不会被隐式调用。即使在你的第一个例子中。仅仅因为您将数据保存到流中并不意味着内存已被释放。大多数情况下,将对象放置在实例化它的同一段代码中是个好主意。这有助于通过提高代码透明度来更轻松地阅读代码。

关于c# - 当我不将 .Save() 的位图 .Dispose() 到 MemoryStream 时,为什么会发生内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8830770/

27 4 0
文章推荐: javascript - vue.js 的