Click to See Complete Forum and Search --> : effect of assigning a NULL


nabeelisnabeel
November 10th, 2008, 01:52 AM
Hi

Lets say we have an object

MyClass o = new MyClass();

and we write following line

o = null;

What will be the effect of assigning a null to some object. Will the actual object allocated on heap be cleaned or just the reference to that object on heap be cleaned and the actual object on heap will be cleaned when Garbage Collector runs?

toraj58
November 10th, 2008, 02:36 AM
Take a look at this links:

http://msdn.microsoft.com/en-us/library/aa691138(VS.71).aspx
http://www.codeproject.com/KB/cs/csavoidnull.aspx

o become eligible for garbage collection when the variable o is assigned the value null.

boudino
November 10th, 2008, 03:50 AM
There are two effects:
1. If the "o" is the only reference to the instance of the MyClass, then the instance becames subject to GC.
2. If you call any method on the "o", then you the NullReferenceException will occure.

darwen
November 10th, 2008, 05:04 AM
You can learn about the .NET CLR garbage collector here ('http://vineetgupta.spaces.live.com/blog/cns!8DE4BDC896BEE1AD!1104.entry').

If you want more details about the inner workings of .NET then buy "CLR via C#" by Richter - it's kind of the bible when it comes to .NET.

Darwen.

TheCPUWizard
November 10th, 2008, 07:36 AM
The ONLYtime you should explicitly assign null (lower call..upper case NULL is a C++ item!) is when the variable holding the reference is going to remain in scope past the point of last use.

In 90%+ of the cases the variable stying in scope longer than the lifetime of the reference is an indication of a bug in the architecture.

Consider:

int f(int x)
{
MyClass c = new MyClass(); /// object created.
// other code
c.SomeMethod(...);
// more code that does NOT use "c", and does not loop back to before the above line
}


c is actually available for garbage collection immediately after the call to c.SomeMethod(...) iun an optimized build.

To make it elegible in a non-optimized build:


int f(int x)
{
{
MyClass c = new MyClass(); /// object created.
// other code
c.SomeMethod(...);
}
// more code that does NOT use "c", and does not loop back to before the above line
}

nabeelisnabeel
November 13th, 2008, 06:34 AM
To make it elegible in a non-optimized build:


int f(int x)
{
{
MyClass c = new MyClass(); /// object created.
// other code
c.SomeMethod(...);
}
// more code that does NOT use "c", and does not loop back to before the above line
}


What do you mean by "To make it elegible in a non-optimized build:" Do you mean that by putting our code in some braces ensures that NULL references be cleaned early.

nabeelisnabeel
November 13th, 2008, 06:36 AM
My actual question was about the deallocation of memory assigned to some objects in heap. Does GC deallocate the memory allocated to some object immediately or does it wait for next GC cycle, when we assign NULL to some object.

boudino
November 13th, 2008, 06:48 AM
No, the memory is not deallocated immediately, but if the GC occures (which can be whenever, based on memory allocation needs). The memory is deallocated if there is no reference, setting to null must not be enought, because the object can be referenced e.g. somewhere in stack or as member variable in other object.

TheCPUWizard
November 13th, 2008, 07:33 AM
1) This depends on your meaning of "Deallocated"....If you mean making the memory available for future calls to new, then boudino is correct...If you mean making it available to the system, that is a completely different. In general once the process aquires memory from the system for Gen0 and Gen1, it is NEVER returned to the OS [until the process exits].


2) For an object to be "released", there must be NO active references (except possible weak references) to the value, and the GC must run for the generation which owns the object. Re-read this until you you start saying this in your sleep.

In an optimized build, then compiler is smart enough to realize where the last possible usage of a variable within a scope is. So immediately after this, even though the reference is in scope, it is not active (see above paragraph).

In a non-optimized build, the compiler treats the reference as active until the actual scope terminates. This makes debugging easier.