Is a memory leak created if a MemoryStream in .NET is not closed?

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.

89471 次浏览
document.getElementById("res").appendChild(x);

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.

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.

Of​​​​​ course there is Mono.

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.

code>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 call Dispose. If you run FxCop on your code, it would flag it as a warning.

I'm no .net expert, but perhaps the problem here is resources, namely the file handle, and not memory. I guess the garbage collector will eventually free the stream, and close the handle, but I think it would always be best practice to close it explicitly, to make sure you flush out the contents to disk.

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.

From the MySQL Manual on LIMIT:

You won't leak memory, but your code reviewer is correct to indicate you should close your stream. It's polite to do so.

To retrieve all rows from a certain offset up to the end of the result

The only situation in which you might leak memory is when you accidentally leave a reference to the stream and never close it. You still aren't really leaking memory, but you are needlessly extending the amount of time that you claim to be using it.

Another approach would be to select an autoimcremented column and then filter it using HAVING.

SET @a := 0;
select @a:=@a + 1 AS counter, table.* FROM table
HAVING counter > 4

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

Another thing I usually do in cases like foo() when creating and returning an IDisposable is to ensure that any failure between constructing the object and the return is caught by an exception, disposes the object, and rethrows the exception:

MemoryStream x = new MemoryStream();
try
{
// ... other code goes here ...
return x;
}
catch
{
// "other code" failed, dispose the stream before throwing out the Exception
x.Dispose();
throw;
}

Just today I was reading about the best way to get huge amounts of data (more than a million rows) from a mysql table. One way is, as suggested, using LIMIT x,y where x is the offset and y the last row you want returned. However, as I found out, it isn't the most efficient way to do so. If you have an autoincrement column, you can as easily use a SELECT statement with a WHERE clause saying from which record you'd like to start.

Disposal of unmanaged resources is non-deterministic in garbage collected languages. Even if you call Dispose explicitly, you have absolutely no control over when the backing memory is actually freed. Dispose is implicitly called when an object goes out of scope, whether it be by exiting a using statement, or popping up the callstack from a subordinate method. This all being said, sometimes the object may actually be a wrapper for a managed resource (e.g. file). This is why it's good practice to explicitly close in finally statements or to use the using statement. Cheers

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()
{
...
}

For example,

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).

SELECT * FROM table_name WHERE id > x;

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;
}
}

The benefit of the using statement (over simply calling dispose) is that you can DECLARE your reference in the using statement. When the using statement finishes, not only is dispose called, but your reference goes out of scope, effectively nullifying the reference and making your object eligible for garbage collection immediately without requiring you to remember to write the "reference=null" code.

I know that this is old but I didnt see a similar response so this is the solution I would use.

While failing to unreference something right away is not a classical "permanent" memory leak, it definitely has the same effect. For example, if you keep your reference to the MemoryStream (even after calling dispose), and a little further down in your method you try to allocate more memory... the memory in use by your still-referenced memory stream will not be available to you until you nullify the reference or it goes out of scope, even though you called dispose and are done using it.

WHERE .... AND id > <YOUROFFSET>
Just check constuctor or flush method of MemoryStream in reflector and it will be clear why you don't need to worry about closing or disposing it other than just for matter of following good practice.