Is a memory leak created if a MemoryStream in .NET

2019-01-02 18:12发布

I have the following code:

MemoryStream foo(){
    MemoryStream ms = new MemoryStream();
    // write stuff to ms
    return ms;
}

void bar(){
    MemoryStream ms2 = foo();
    // do stuff with ms2
    return;
}

Is there any chance that the MemoryStream that I've allocated will somehow fail to be disposed of later?

I've got a peer review insisting that I manually close this, and I can't find the information to tell if he has a valid point or not.

12条回答
姐姐魅力值爆表
2楼-- · 2019-01-02 18:28

If something is Disposable, you should always Dispose it. You should be using a using statement in your bar() method to make sure ms2 gets Disposed.

It will eventually get cleaned up by the garbage collector, but it is always good practice to Dispose. If you run FxCop on your code, it would flag it as a warning.

查看更多
浅入江南
3楼-- · 2019-01-02 18:29

This is already answered, but I'll just add that the good old-fashioned principle of information hiding means you may at some future point want to refactor:

MemoryStream foo()
{    
    MemoryStream ms = new MemoryStream();    
    // write stuff to ms    
    return ms;
}

to:

Stream foo()
{    
   ...
}

This emphasizes that callers should not care what kind of Stream is being returned, and makes it possible to change the internal implementation (e.g. when mocking for unit testing).

You then will need be in trouble if you haven't used Dispose in your bar implementation:

void bar()
{    
    using (Stream s = foo())
    {
        // do stuff with s
        return;
    }
}
查看更多
公子世无双
4楼-- · 2019-01-02 18:31

All streams implement IDisposable. Wrap your Memory stream in a using statement and you'll be fine and dandy. The using block will ensure your stream is closed and disposed no matter what.

wherever you call Foo you can do using(MemoryStream ms = foo()) and i think you should still be ok.

查看更多
谁念西风独自凉
5楼-- · 2019-01-02 18:36

If an object implements IDisposable, you must call the .Dispose method when you're done.

In some objects, Dispose means the same as Close and vice versa, in that case, either is good.

Now, for your particular question, no, you will not leak memory.

查看更多
其实,你不懂
6楼-- · 2019-01-02 18:39

Calling .Dispose() (or wrapping with Using) is not required.

The reason you call .Dispose() is to release the resource as soon as possible.

Think in terms of, say, the Stack Overflow server, where we have a limited set of memory and thousands of requests coming in. We don't want to wait around for scheduled garbage collection, we want to release that memory ASAP so it's available for new incoming requests.

查看更多
大哥的爱人
7楼-- · 2019-01-02 18:44

You won't leak anything - at least in the current implementation.

Calling Dispose won't clean up the memory used by MemoryStream any faster. It will stop your stream from being viable for Read/Write calls after the call, which may or may not be useful to you.

If you're absolutely sure that you never want to move from a MemoryStream to another kind of stream, it's not going to do you any harm to not call Dispose. However, it's generally good practice partly because if you ever do change to use a different Stream, you don't want to get bitten by a hard-to-find bug because you chose the easy way out early on. (On the other hand, there's the YAGNI argument...)

The other reason to do it anyway is that a new implementation may introduce resources which would be freed on Dispose.

查看更多
登录 后发表回答