| [ directory ] |
|
4.8 Object DestructionAs mentioned in Chapter 1, Java and C# provide automatic garbage collection. Therefore, objects allocated in memory are reclaimed by the runtime environment without any special coding by the programmer. This feature alone makes programming in Java and C# easier than in C++. However, programmers need some knowledge of memory management and garbage collection to avoid making mistakes that would hamper the garbage collection process. The java.lang.Object class provides a finalize() method that gets called during garbage collection. You cannot control the order and timing of this call. Nonetheless, Java programmers tend not to use finalizers for memory management for the following reasons:
C# is no different when it comes to memory management. Even though you can make extern DLL calls to reclaim memory in the destructor, such coding practices are the exception and not the norm. Sometimes you need to release non-memory-based resources in a more timely manner. Releasing such resources in the finalize() method is not recommended at all. Nor should these resources (file handles, database connections) be released in the destructor. In Java, a resource typically is released in the finally block:
Resource res = null;
try {
res = getResource();
} finally {
freeResource(res);
}
C# provides a similar paradigm and goes further in facilitating the release of resources using the IDisposable interface. The IDisposable interface provides a Dispose() method by which the classes can free up resources. Listing 4.16 shows a class that implements the IDisposable interface. Listing 4.16 Using the IDisposable Interface
using System;
using System.Runtime.InteropServices;
public class DatabaseWrapper : IDisposable {
int handle = 0;
public DatabaseWrapper() {
handle = GetNewHandle();
}
public void Dispose() {
FreeHandle(handle);
GC.SuppressFinalize(this);
}
[DllImport("dll.dll")]
static extern int GetNewHandle();
[DllImport("dll.dll")]
static extern void FreeHandle(int handle);
static void Main(string[] args) {
DatabaseWrapper dw = null;
try {
dw = new DatabaseWrapper();
} finally {
dw.Dispose();
}
}
}
C# also provides the using construct, letting you avoid the try-finally block. Therefore,
using (DatabaseWrapper dw = new DatabaseWrapper()) {
//Use the dw object to do stuff here
}
The using block will take care of calling the Dispose() method properly. |
| [ directory ] |
|