我从MSDN获得了一个流示例,我加倍可能存在资源泄漏问题。例如,如果li {
background-color: orange;
}
或其他代码行发生异常,那么它是否可能导致<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ul">
<li>a</li>
<li>as</li>
<li>dsk</li>
</ul>
的资源泄漏?
readStream.ReadToEnd()
答案 0 :(得分:3)
这个例子确实缺乏适当的资源处理,例如经常这样做。这是作者的错,他更喜欢简洁优于良好的编码实践。
HttpWebRequest
,Stream
和StreamReader
都应该包含using
个阻止。
答案 1 :(得分:2)
是
这是一个例子,不是一个好习惯。它的优化是为了清晰,而不是正确。通常,MSDN示例不能复制到您的代码中。它们通常对于现实生活来说太简单(很少处理错误等)或太具体。我甚至看到一些完全错误的东西(例如,假设一侧的单个TCP写入的网络样本对应于另一侧的单个TCP读取);你所能做的就是报告这些并对其进行评论。
但是,泄漏不一定是一个问题 - 它对托管对象没有影响(无法强制销毁托管对象),并且最终将清理所有非托管对象假设它们都由其所有者正确管理(例如,SafeHandle
将自动处理基础句柄,如果您忘记了)。如果您想更好地理解这一点,请阅读.NET终结器。简而言之,如果未通过明确的Dispose
(与using (stream) { ... }
一样)清理了非托管资源,则终结工具将清理非托管资源。
当然,有些情况下,依赖GC并不是一种不好的做法,但是完全错了。最明显的例子(我在软件中经常看过很多次)是忘记关闭一个打开的文件,然后尝试再次使用文件共享冲突打开它。在最糟糕的情况下,它甚至可能不是确定性错误 - 也许某些操作会引入足够的内存压力并花费足够的时间让终结器关闭文件有时,并且错误只显示其丑陋很少,你有一个非常丑陋的虫子很难重现。
更进一步,没有真正要求一致的.NET实现首先包含垃圾收集器,或者GC需要它的工作方式。比方说,一个.NET运行时,它允许你的应用程序的内存增长,直到无法增长,然后抛出OutOfMemoryException
将是完全合法的(对于某些类型的应用程序,非常有用)。一个好的实现将跟踪托管资源,但非托管资源始终是您的责任 - 如果它实现IDisposable
,您的工作就是调用它(通常使用using
)。在一个完美的.NET应用程序中,终结器永远不会运行 - 它们是一个安全网,如果你继续使用安全网,那你就错了。