Free mag vol1 | Page 534

CHAPTER 13  UNDERSTANDING OBJECT LIFETIME The Basics of Object Lifetime When you are building your C# applications, you are correct to assume that the .NET runtime environment (a.k.a. the CLR) will take care of the managed heap without your direct intervention. In fact, the golden rule of .NET memory management is simple:  Rule Allocate a class instance onto the managed heap using the new keyword and forget about it. Once instantiated, the garbage collector will destroy an object when it is no longer needed. The next obvious question, of course, is, “How does the garbage collector determine when an object is no longer needed?” The short (i.e., incomplete) answer is that the garbage collector removes an object from the heap only if it is unreachable by any part of your code base. Assume you have a method in your Program class that allocates a local Car object as follows: static void MakeACar() { // If myCar is the only reference to the Car object, // it *may* be destroyed when this method returns. Car myCar = new Car(); } Notice that this Car reference (myCar) has been created directly within the MakeACar() method and has not been passed outside of the defining scope (via a return value or ref/out parameters). Thus, once this method call completes, the myCar reference is no longer reachable, and the associated Car object is now a candidate for garbage collection. Understand, however, that you can’t guarantee that this object will be reclaimed from memory immediately after MakeACar() has completed. All you can assume at this point is that when the CLR performs the next garbage collection, the myCar object could be safely destroyed. As you will most certainly discover, programming in a garbage-collected environment greatly simplifies your application development. In stark contrast, C++ programmers are painfully aware that if they fail to manually delete heap-allocated objects, memory leaks are never far behind. In fact, tracking down memory leaks is one of the most time-consuming (and tedious) aspects of programming in unmanaged environments. By allowing the garbage collector to take charge of destroying objects, the burden of memory management has been lifted from your shoulders and placed onto those of the CLR. The CIL of new When the C# compiler encounters the new keyword, it emits a CIL newobj instruction into the method implementation. If you compile the current example code and investigate the resulting assembly using ildasm.exe, you’d find the following CIL statements within the MakeACar() method: .method private hidebysig static void MakeACar() cil managed { // Code size 8 (0x8) .maxstack 1 .locals init ([0] class SimpleGC.Car myCar) IL_0000: nop IL_0001: newobj instance void SimpleGC.Car::.ctor() 475