Bitmap.Save,巨大的内存泄漏

我有一个应用程序,我正在使用位图并使用GZipStream压缩它并通过套接字将其发送到内存中。 我已经将脏的scumbag内存泄漏跟踪到以​​下行:

frame.Save(inStream, jpegCodec, parameters); 

浏览好的信息高速公路我发现了很多关于Image类泄漏内存的主题在各种编解码器的保存方法中。 问题是我找不到任何修复方法。 所以我的问题如下:

  1. 是什么原因造成的
  2. 我怎样才能解决这个问题

这是我的FrameStream类中的完整Write()方法,其中包含泄漏。

 ///  /// Writes a frame to the stream ///  /// The frame to write public void Write(Bitmap frame) { using (EncoderParameter qualityParameter = new EncoderParameter(Encoder.Quality, 50L)) { using (EncoderParameters parameters = new EncoderParameters(1)) { parameters.Param[0] = qualityParameter; ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo jpegCodec = null; foreach (ImageCodecInfo codec in codecs) { if (codec.MimeType == "image/jpeg") { jpegCodec = codec; break; } } using (MemoryStream inStream = new MemoryStream()) { frame.Save(inStream, jpegCodec, parameters); // HUUUGE Memory Leak Byte[] buffer = new Byte[inStream.Length]; inStream.Read(buffer, 0, buffer.Length); using (MemoryStream outStream = new MemoryStream()) { using (GZipStream gzipStream = new GZipStream(outStream, CompressionMode.Compress)) { gzipStream.Write(buffer, 0, buffer.Length); } Byte[] frameData = outStream.ToArray(); Byte[] packet = new Byte[15 + frameData.Length]; Byte[] frameLength = BitConverter.GetBytes(frameData.Length); Array.Copy(frameLength, 0, packet, 0, frameLength.Length); Array.Copy(frameData, 0, packet, 15, frameData.Length); m_Socket.Send(packet); } } } } } 

我建议在CLR Profiler下运行你的代码来找到泄漏源。 如果它是任何类型的托管对象(甚至是非托管资源),只要该漏洞不是由于托管类型泄漏非托管句柄,您就能够看到泄漏的位置。 如果它在框架代码中,您可以使用reflection和P / Invoke来解决它。

例如,在某些情况下, Icon类型会泄漏Win32 HICON 。 解决方法是使用Icon公开的句柄通过PInvoking DeleteObject函数手动配置HICON

好吧,在尝试了每个人的想法和想法以及许多其他方法之后。 我终于尝试了简单:

 using (frame) { frame.Save(outStream, jpegCodec, parameters); } 

好吧,这工作和内存泄漏是固定的..我试图强制调用垃圾收集器,手动处理位图,使用P / Invoke DeleteObject,没有任何工作,但使用using语句。 所以这让我想知道在我错过的使用声明中会发生什么。

在处理完成后,您应该将位图设置为null。

此外,您可能希望在处理Bitmap后调用垃圾收集器(即使这是一项昂贵的操作): GC.Collect();

位图保存非托管资源 – GC并不总是“在球上”。 这是一个关于Bitmap类的有趣链接(从紧凑框架的角度来看): http : //blog.opennetcf.com/ctacke/PermaLink,guid,987041fc-2e13-4bab-930a-f79021225b74.aspx

我不太了解套接字。 但是,我知道使用Image类来阻止内存泄漏的一种方法是冻结位图。 希望这篇文章可能会为您提供更多信息。 MemoryStream.Dispose会失败吗? 从而,造成内存泄漏。

你在调用Graphics对象的.Dispose()方法吗? 这导致内存泄漏。 编辑:一旦你写了字节[],你现在很清楚Bitmap对象的.Dispose()。