如何解决在这种情况下,“不处理StreamWriter”会导致memoryLeak吗?
| 我有如下方法public int TranslateOOV(string word,Stream logStream)
{
StreamWriter writer = new StreamWriter(logStream);
//Do some logging
//dont close the writer and leave the caller close the stream
}
我不关闭StreamWriter,因为调用者应关闭内部流,这会导致内存泄漏吗?
解决方法
只是为了好玩,我才打开反编译器,看看Dispose对StreamWriter的作用(认为底层流可能是唯一需要处理的资源)。结果如下:
protected override void Dispose(bool disposing)
{
try
{
if (this.stream != null)
{
if (disposing || (this.Closable || this.stream as __ConsoleStream))
{
this.Flush(true,true);
if (this.mdaHelper != null)
{
GC.SuppressFinalize(this.mdaHelper);
}
}
}
}
finally
{
if (this.Closable)
{
if (this.stream != null)
{
if (disposing)
{
this.stream.Close();
}
this.stream = null;
this.byteBuffer = null;
this.charBuffer = null;
this.encoding = null;
this.encoder = null;
this.charLen = 0;
base.Dispose(disposing);
}
}
}
}
有点罗word,但是我认为这告诉我们的是,处理流只处理StreamWriter使用的唯一Disposable资源。 byteBuffer
和charBuffer
字段是数组,encoding
和encoder
不是一次性的,而基Dispose
是虚拟的,因此,如果不对其进行清理,则Stream是唯一会引起问题的东西。
我认为这也很清楚,如果您要记录流的内容并在之后将其保持可用状态,那么您绝对会不想处置您的StreamWriter,因为这将处置Stream(Close调用) Dispose(true)
)。您还需要确保重设Stream的位置,因为毫无疑问,您将通过阅读内容来更改它的位置。当然,这也意味着您可能想要检查Stream上的CanSeek
属性,并确保一旦阅读内容,便可以将位置恢复到之前的位置。
, 作为最佳实践,您应该在不再需要它时立即将其关闭。但是,垃圾回收离开本地函数作用域时应将其标记为清理。
, 如果不再引用该流,则该流肯定会被垃圾收集器丢弃,因为它实现了IDisposable。
让垃圾收集器进行处理的问题在于,处理垃圾的时间不确定,取决于多个条件。
因此,从理论上讲,它不会导致内存泄漏,但是它将使您的应用程序在更长的时间内使用更多的资源,这可能是非常低效的。
, 这不是我的强项,但是是的,您应该将StreamWriter放入Using()块中,处置流写入器不应处置流。如果确实要处理流,则需要返回流编写器引用,以便进一步对其进行清理。
编辑:在Microsoft上的大杂烩编码。 StreamWriter不会处理流,因为您可以直接在@ckramer的答案上看到它对流进行了“ 9”处理。深入研究close方法http://msdn.microsoft.com/en-us/library/system.io.stream.close.aspx
此方法调用Dispose,将其指定为true以释放所有资源。您不必专门调用Close方法。相反,请确保正确处理每个Stream对象。
很高兴看到Microsoft直接忽略了他们自己的声明。它仍然变得更好。
实施者须知
在派生类中,请勿覆盖Close方法,而应将所有Stream清理逻辑放入Dispose方法中。
这绝对没有道理。因此,他们不仅忽略了他们的第一条语句,而且创建了一个违反开放式封闭原则的类,使您能够以可能导致意外情况的方式修改该类。对于这样的语句,Close绝对不应该是虚拟的,否则他们应该已经解决了考虑到的任何原因。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。