我遇到有关.NET内存泄漏的问题。
我有一个非常复杂的项目,一个线程又一个线程,很难调试。
我知道Abort()
已贬值,但我有使用它们的理由:
我的方法是与网络相关的I / O长方法。没有可以在其中放入标记的明确的耗时操作。如果我到处都放标志,代码将一团糟。
需要时,线程必须立即终止,越早越好。不再需要内部的所有工作。
当我正常运行程序时,线程完成工作并自然地一个接一个地死掉,一切正常(我已经运行了2年,没有内存泄漏)。
但是,如果我尝试创建新线程,Start()
和Abort()
经常创建它们(每秒1-2个线程,比不使用abort()
的情况要快一点),那么内存泄漏。
更有线的是,在操作完成后,占用的内存将保持高电平一段时间,例如数分钟或10分钟,但最终会恢复正常,就像什么也没发生一样。
在调试模式下,我看不到活动线程,但内存泄漏。
因此,我使用了.NET内存分析器进行跟踪。 byte[]
引用了许多MemoryStream
所占用的内存,大多数实例。
是的,我确实使用MemoryStream
,但是我所有的MemoryStream
都在using
块内,也不例外。一切都应正确放在using
块中。
据我所知,Thread.Abort()
抛出了一个异常以强制关闭它,但是正如我在调试模式下确认的那样,所有线程都已关闭。为什么仍然有参考?为什么一段时间后释放内存? (但比不放弃线程并让它完成工作的情况要长得多。)
IMO using
块可以保证即使将ThreadAbortException
扔到Dispose()
中也可以正确执行。
编辑:
public static byte[] Recover(byte[] png)
{
using (MemoryStream pngStream = new MemoryStream(png))
{
using (System.Drawing.Image image = System.Drawing.Image.FromStream(pngStream))
{
using (MemoryStream bmpStream = new MemoryStream())
{
image.Save(bmpStream, System.Drawing.Imaging.ImageFormat.Bmp);
bmpStream.Seek(0, System.IO.SeekOrigin.Begin);
byte[] BMP = new byte[bmpStream.Length];
bmpStream.Read(BMP, 0, (int)bmpStream.Length);
return BMP;
}
}
}
}
public xxxxMission(byte[] png, Server server, int no) //constructor
{
byte[] bmp = xxxBMP.Recover(png); //png is generated by getBlankBMP();
//....
}