Deterministic Finalization and Garbage Collection

Deterministic Finalization and Garbage Collection

Garbage collection is a new concept to Windows platform development. It is quite a departure from the COM memory-management mechanism of reference counting and offers significant benefits. In COM, objects use reference counting to keep track of the number of active references to determine their lifetime. When an object s reference count reaches zero, the object is destroyed. Reference counting presents several problems within COM because of issues with potential reference leaks or circular references. However, it is, for the most part, predictable. Reference counting makes it possible to determine when and where an object will be destroyed and, as a result, to manipulate the lifetime of the object in a deterministic way hence the term deterministic finalization.

Visual Basic 6 made COM programming much simpler because it hid a great deal of the COM implementation details. But you could rely on Visual Basic s behavior with respect to COM object lifetimes. The following example illustrates how reference counting in Visual Basic 6 can influence an object s lifetime:

Dim x As Connection, y As Connection Set x = new Connection 'Create an object and set refcount = 1 Set y = x       'set refcount = 2 Set x = Nothing 'set refcount = 1 Set y = Nothing 'set refcount = 0; and destroy the object

It is not necessary to explicitly dereference your objects in Visual Basic 6. When a variable goes out of scope, Visual Basic 6 automatically dereferences the object for you:

Sub MySub()    Dim x As Connection, y As Connection    Set x  = New Connection 'Create an object and set refcount = 1    Set y = x   'set refcount = 2 End Sub

In Visual Basic .NET, the picture is drastically different. For the most part, it is no longer possible to determine the exact lifetime of a given object because Visual Basic .NET does not use reference counting. Instead, it handles memory management through garbage collection. Putting aside the implementation details, this change produces distinct behavioral differences that will have implications for your applications. First of all, setting a reference to Nothing will not cause that object to be immediately destroyed. Garbage collection guarantees that the object will be destroyed at some point, but there is no guarantee as to when it will be destroyed.

The effects of this change are best illustrated by the following code in Visual Basic .NET:

Dim conn As New ADODB.Connection conn.Open( ... ) Dim rs = conn.Execute( ... ) conn = Nothing  ' The object is not destroyed here and the                  ' connection is still open

note

You might ask why Microsoft chose to make this change from a deterministic memory-management scheme to a nondeterministic one such as garbage collection. The general consensus was that too much of COM programming was related to memory-management issues. Garbage collection frees the developer from many of these arduous tasks, enabling the developer to focus more on designing program logic then on memory management. It does require a slightly different programming approach when dealing with objects that represent physical system resources. For the most part, though, you don t really need to worry about it. Garbage collection is quite a positive change and should result in fewer problems with memory leaks in your applications.

In Visual Basic 6, we could rely on setting the conn reference to Nothing to close the connection and destroy the underlying Connection object. In Visual Basic .NET, setting conn to Nothing simply marks the object for collection. The underlying physical connection to the database remains open, consuming both memory and network resources. Thus, it is imperative when working with objects that represent real physical resources (such as files, graphics handles, and database connections) that you explicitly release those resources before you dereference the object (or allow it to go out of scope). A proper way to handle this would be as follows:

Dim conn As New ADODB.Connection conn.Open( ... ) Dim rs = conn.Execute( ... ) conn.Close() conn = Nothing

The Close method ensures that the database connection is released immediately. This is by far the best way to handle any physical resource. Whenever you deal with a physical resource, follow this general rule: open the resource as late as possible and release it as soon as possible. This practice will ensure the most efficient use of system resources.

Bringing a Little Determinism to the Party

It is possible to ensure that your objects are destroyed before your application proceeds. To do so, you need to cause a garbage collection to occur and then wait for the collection to complete. You can accomplish these tasks by calling the following two methods.

GC.Collect() GC.WaitForPendingFinalizers()

It is pretty obvious that the first method causes a collection to occur. You need to realize, however, that the Collect method is an asynchronous call (hooray, free threading!), meaning that your application will not wait for the collection to complete before continuing. That is why it is important to call WaitForPendingFinalizers, which will block your application until the collection has completed.

Now that you ve seen how forcing garbage collection can be done, here is why you should almost never do it: Garbage collection is, by definition, an expensive operation. For this reason, it takes place relatively infrequently, instead of whenever and wherever an object is dereferenced. If you have code that needs to work no matter what, then by all means take advantage of Collect and WaitForPendingFinalizers. Ultimately, however, this technique is just a quick fix. For the long term, you should probably investigate how to eliminate this dependency.



Upgrading Microsoft Visual Basic 6.0to Microsoft Visual Basic  .NET
Upgrading Microsoft Visual Basic 6.0 to Microsoft Visual Basic .NET w/accompanying CD-ROM
ISBN: 073561587X
EAN: 2147483647
Year: 2001
Pages: 179

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net