我最近一直在使用DotSpatial库,并注意到我的程序泄漏了相当严重的内存。我一直在使用VS内存诊断工具,并设法将问题缩小到以下(简化的)代码块:
using (var inMemoryStream = new MemoryStream())
using (var _writer = new BinaryWriter(inMemoryStream))
{
WriteHeader(_writer);
_writer.Close();
}BinaryWriter对象维护对inMemoryStream对象的引用,并将该引用分配给该对象的OutStream属性。似乎无论使用哪种处理方法(使用/ close / dispose),此内存流都不会释放它为其缓冲区分配的内存。
我已经设法解决了这个问题,方法是创建一个继承自BinaryWriter的类,覆盖Close()并向方法添加"OutStream = null“,但这似乎很笨拙。
我是不是遗漏了什么?难道BinaryWriter不应该完全处理传递给它的流吗?看起来好像BinaryWriter.Close()确实试图达到这个效果,因为使用智能感知查看OutStream的一些属性会显示一个ObjectDisposed异常。我使用的是.NET 4.5.2,如果有区别的话。
提前感谢您的开悟
发布于 2018-04-24 22:53:11
你似乎认为Dispose的意思是“清理引用”。有时可能会出现这种情况,但Dispose的实际目的是释放非托管资源。虽然有许多滥用Dispose的其他用途(由于方便的using语法等),但您不应该期望比这更多。
关闭文件将释放非托管资源。关闭数据库连接将释放非托管资源。是否删除对另一个托管对象的引用?为什么你会期望这会成为Dispose的一部分呢?在丢弃引用之前调用Dispose -无论如何,以后都不能重用它,也不能以任何方式使用已释放的对象。
当然,在某些情况下,这可能会导致内存泄漏。但在这种情况下,内存泄漏一直存在- Dispose只能使其更小。当然,这本身是值得的,但解决方案仍然是修复问题并释放引用,而不是试图找到减少泄漏资源量的方法。
发布于 2018-04-24 22:55:52
Dispose不释放托管内存。这是垃圾收集器的工作。因此,尽管仍然可以从程序的作用域(即所有静态变量或当前局部变量)访问对MemoryStream的引用,但不会释放内存。
即使MemoryStream不再被引用,也要由GC决定何时释放内存。它不一定是立即的,甚至不是很快的。这取决于其他因素,如总体内存压力。
https://stackoverflow.com/questions/50004525
复制相似问题