Page 1 of 1

Local variable doesn't get GCed

Posted: Tue Aug 07, 2012 8:20 pm
by mnn
I have something like this:

Code: Select all

using (var obj = new MyObject()) // obj holds reference to a stream, thus is disposable
{
    var something = GetSomething(obj); // something holds reference to obj

    // working...
}
If I do snapshot in .NET Memory Profiler right after obj is disposed by using, something is still alive and keeps obj alive.

Do I really need to manually remove the reference before disposing obj?

Re: Local variable doesn't get GCed

Posted: Thu Aug 09, 2012 7:13 am
by Andreas Suurkuusk
No, there's no need to remove the reference before calling Dispose. "something" is most likely still alive because you have compiled your code in Debug mode. When debug mode is used, the scope of variable might be longer than expected, to make debugging easier.

Consider the following code:

Code: Select all

void SomeMethod()
{
    SomeClass someClass = new SomeClass();

    MemProfiler.FullSnapShot();
}
If this code is compiled as "Debug", an instance of SomeClass will be kept alive by the SomeMethod method. On the other hand, if the code is compiled as "Release", the SomeClass instance will have been GCed at the time of the snapshot.

This behaviour can be mitigated by explicitly setting the variable to null (see code below). However, that's not something I would recommend, as it adds unnecessary code and changes the scope of the variable (in a Release build).

Code: Select all

void SomeMethod()
{
    SomeClass someClass = new SomeClass();

    someClass = null;

    MemProfiler.FullSnapShot();
}