6

想知道以下情况是否会导致任何内存泄漏。

Aspx 页面包含以下内容。

private void Generator(input)
{
    using (MemoryStream memoryStream = Helper.Instance.Generate(input))
    {
    }
}

下面的方法是从返回内存流的 aspx 页面调用的。

MemoryStream Generate(input)
{
    MemoryStream stream = new MemoryStream();
    //doing some stream manipulation here

    return stream;
}
4

4 回答 4

10
  • 第一点:如果代码抛出异常:

    // doing some stream manipulation here
    

    那么 MemoryStream 不会被返回Helper.Instance.Generate,所以不会被调用者处理掉。

  • 第二点:MemoryStream不使用任何非托管资源,所以调用Dispose.

所以在这种情况下不会有内存泄漏。

Helper.Instance.Generate如果抛出异常,那么强制 Dispose 可能会更好:

MemoryStream Generate(input)  
{      
    MemoryStream stream = new MemoryStream();      

    try
    {
        //doing some stream manipulation here        

        return stream;  
    }
    catch
    {
        stream.Dispose();
        throw;
    }
}  

这是构造、操作和返回IDisposable对象的方法的一般模式。

于 2012-09-18T12:24:48.817 回答
0

我认为始终如一地处理诸如MemoryStream, DataTable, ... 之类的东西是有价值的,这使得阅读代码和验证它是否正确变得更容易。如果您在using-block 中看到资源,您就知道它是正确的。无需在脑海中进行心理流动追踪和模拟执行。

可以立即验证代码是否正确。完全没有思考。我认为这很好。

也就是说,虽然我尝试将不必要的东西放入using块中,但我不会过度使用它。如果有理由不处理它(即使是开发人员的便利),我只是不处理。

于 2012-09-18T12:39:07.147 回答
0

@Joe 已经提供了一些解释。对于实现 IDisposable 的对象,您可以尽早调用 Dispose 以回收资源(托管和/或非托管),但您可以决定不调用,因为 CLR 仍会跟踪它们并将通过终结器回收资源。通过终结器释放资源需要更多时间,但可以防止发生内存泄漏。

只有当实现对象/类的人没有遵循设计准则并且忘记正确编写终结器时,才会发生内存泄漏。

有大量的文章和书籍提到了细节,例如

http://msdn.microsoft.com/en-us/magazine/cc163392.aspx

http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae

于 2012-09-18T12:52:03.997 回答
0

这是完全有效的,并且不会产生内存泄漏,因为 Dispose 方法是在退出 using 块后调用的。

与执行以下操作完全相同:

 private void Generator(input)
 {
    using (MemoryStream memoryStream = new MemoryStream())
    {
        Helper.Instance.Manipulate(memoryStream);
    }
 }
于 2012-09-18T12:18:21.050 回答