Search code examples
c#memory-management.net-4.0memory-leaksusing

Returning disposable object from within using block


I'm noticing a lot of byte[] getting stuck in memory when profiling my program. I did some digging and found the majority of the instances created in some manner like this:

public byte[] CreateBytes(byte[] bytes)
{
    using (var start = new MemoryStream()) 
    {
        using (var memStr = new MemoryStream(bytes))
        {
            //do stuff
            return start.ToArray();
        }
    }
}

The returned byte[] is then passed to other methods and is used in creating another MemoryStream from within another using block:

using (var uncompressedStream = new MemoryStream(uncompressedData))
{
    using (var compressedStream = new MemoryStream())
    {
        //Do some compression
    }
}

myObject.Bytes = uncompressedData;
uncompressedData = null;

return myObject;

(uncompressedData is the value returned from CreateBytes()).

My question is, when does the byte[] get cleaned up? Do I specifically need to set it to null, and if so, where? After the second using block I no longer need it, but if I simply put uncompressedData = null; I'm not sure that's going to reclaim the memory.

I would've thought that the using statement in CreateBytes(byte[] bytes) would've disposed of the bytes, but since it's returning a reference does that postpone and/or forego the disposal?

EDIT: I added another line of code. Since I'm storing the uncompressedBtyes in another object, setting uncompressedData to null is pointless and the byte[] will live as long as myObject (or until myObject.Bytes is set to null), correct?


Solution

  • The byte[] gets cleaned up when two conditions are both satisfied:

    • There are no references to that memory block
    • The garbage collector decides to collect that memory block

    The GC runs at non-deterministic times based on a variety of factors.