Datasheet
you restrict your classes to exposing only CLS-compliant features, code written in any other compliant
language can use your classes.
The beauty of this idea is that the restriction to using CLS-compliant features applies only to public and
protected members of classes and public classes. Within the private implementations of your classes, you
can write whatever non-CLS code you want, because code in other assemblies (units of managed code,
see later in this chapter) cannot access this part of your code anyway.
We won’t go into the details of the CLS specifications here. In general, the CLS won’t affect your C# code
very much, because there are very few non-CLS-compliant features of C# anyway.
Garbage Collection
The garbage collector is .NET’s answer to memory management, and in particular to the question of what
to do about reclaiming memory that running applications ask for. Up until now, two techniques have
been used on the Windows platform for deallocating memory that processes have dynamically requested
from the system:
❑ Make the application code do it all manually.
❑ Make objects maintain reference counts.
Having the application code responsible for deallocating memory is the technique used by lower-level,
high-performance languages such as C++. It is efficient, and it has the advantage that (in general) resources
are never occupied for longer than necessary. The big disadvantage, however, is the frequency of bugs.
Code that requests memory also should explicitly inform the system when it no longer requires that
memory. However, it is easy to overlook this, resulting in memory leaks.
Although modern developer environments do provide tools to assist in detecting memory leaks, they
remain difficult bugs to track down, because they have no effect until so much memory has been leaked
that Windows refuses to grant any more to the process. By this point, the entire computer may have
appreciably slowed down due to the memory demands being made on it.
Maintaining reference counts is favored in COM. The idea is that each COM component maintains a
count of how many clients are currently maintaining references to it. When this count falls to zero, the
component can destroy itself and free up associated memory and resources. The problem with this is
that it still relies on the good behavior of clients to notify the component that they have finished with it.
It only takes one client not to do so, and the object sits in memory. In some ways, this is a potentially
more serious problem than a simple C++-style memory leak, because the COM object may exist in its
own process, which means that it will never be removed by the system (at least with C++ memory leaks,
the system can reclaim all memory when the process terminates).
The .NET runtime relies on the garbage collector instead. This is a program whose purpose is to clean up
memory. The idea is that all dynamically requested memory is allocated on the heap (that is true for all
languages, although in the case of .NET, the CLR maintains its own managed heap for .NET applications
to use). Every so often, when .NET detects that the managed heap for a given process is becoming full
and therefore needs tidying up, it calls the garbage collector. The garbage collector runs through variables
currently in scope in your code, examining references to objects stored on the heap to identify which
ones are accessible from your code — that is to say which objects have references that refer to them. Any
13
Chapter 1: .NET Architecture
24727c01.qxd:WroxPro 5/7/07 12:12 PM Page 13