<a href="http://www.micropoll.com/akira/mpview/585320-168921">Click Here for Poll</a><a href="http://www.questionpro.com" title="online surveys">Online Survey</a><BR> | <a href="http://www.micropoll.com" title="Website Polls">Website Polls</a><BR> | <BR><a href="http://www.micropoll.com/akira/MicroPoll?mode=html&id=168921">View MicroPoll</A></div>

Visual Studio 2010!

Read now >

Windows Mobile Development Thoughts

Read now >

View Now
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.
ADVERTISEMENT
ADVERTISEMENT

 

DevSource.com: Your Source for Visual Studio on Facebook
ADVERTISEMENT
.NET Memory Management and Finalization
By Max Loukianov

Rate This Article: Add This Article To:

.NET Memory Management and Finalization - ' Finalization Issues '
( Page 5 of 5 )

Issues with Finalization and Rules of Finalization

All is not perfect. There are some issues you should be aware of.

1. Referring to other finalizable objects from Finalize()

One of the guidelines for Finalization is that the Finalize() method should not touch other objects. One may assume (incorrectly) that this is because those objects have already been collected; however, as we saw above, all objects reachable from a finalizable object are promoted.

The real reason for the guideline is that finalization is unordered and other objects may already be finalized. Note that this applies only to finalizable objects. For example, if your object "owns" a private object that is not finalizable, you can refer to that object from the Finalize() method without any risk.

Whidbey solves the problem of referencing one finalizable object from another by using the semantics of critical finalization. In addition, it is quite likely that in the future, two Finalize() methods might be executed simultaneously from two different threads.

2. Finalization is unordered

The fact is that finalization is unordered. Let's consider some reasons behind it.

First, in many cases, no natural order is possible. Often, finalizable objects occur in cycles; ordering references and providing ordered finalization would substantially slow down the garbage collection process. At the same time, it is quite possible that reference would cross generational boundaries, which would make finalization algorithms substantially more complicated.

Unordered finalization is substantially faster. The finalization algorithm not only avoids sorting but also makes very efficient use of RegisteredForFinalization and ReadyToFinalize queues. Finally, there is value in making developers write finalization code as simply as possible. In future, it is expected that finalization would be performed by multiple threads to improve scalability and to make it more robust.

3. Finalization and permissions

There are no security permissions associated with the definition of the Finalize() method, therefore a partially trusted code is allowed to participate in finalization. Typically, Finalize() methods are used to release unmanaged resources, since the resources are typically outside of the application control.

What's New in Whidbey Finalization Support?

Whidbey provides new mechanisms that address some of the issues with finalization in .NET 1.0 and 1.1. New features include SafeHandles, CriticalFinalizers, and Constrained Execution Regions.

Conceptually, SafeHandle is just an encapsulation of an OS handle. SafeHandle provides several benefits. First, somebody else already wrote it. You do not have to re-implement the same functionality; it is much easier to use an existing one.

SafeHandle prevents a race condition between an application thread and a finalizer thread. The finalizer thread is a high priority, but not a critical priority thread. Therefore, a race condition is theoretically possible, but the SafeHandle implementation takes care of that. SafeHandle makes clients deal with the encapsulation, not with IntPtrs or value types.

SafeHandle uses a new Critical Finalization mechanism to prevent memory leaks. Critical Finalization guarantees that the Finalize() method will actually be called, and that it will complete execution.

Critical Finalization affects any object that derives from the CriticalFinalizerObject (including the SafeHandle we just looked at). Critical Finalization will provide the following guarantees:

  • The CLR will prepare any resources necessary for the Finalize() method to run before objects are created. Preparation includes JIT'ing the code, executing class constructors, and traversing the reachability of other methods and types that are required during execution of Finalize(), and making sure they are prepared in the same way. However, the CLR can not traverse through interface calls (since they have no information about implementation) and virtual calls (for the same reason).
  • The CLR will never timeout on execution of a Finalize() method in Critical Finalization. When the Finalize() method is called by the Finalizer thread, it is in a protected state that prevents the CLR from injecting Thread.Aborts or other async exceptions. One exception is the OutOfMemoryException, which may get injected if the application tries to allocated an object and there is not enough memory. However, this is considered an application responsibility, since it is was system-induced. The Finalize() method can use standard methods of exception handling to protect itself.
  • In addition to all the above, all normal finalizable objects are either executed or discarded without finalization before any finalizers in Critical Finalization are executed.

Constrained Execution Regions (CERs) address issues with async exceptions in the CLR. Async exceptions are different from application-level exceptions, which are anticipated by and handled by the application code. CERs allow you to declare regions of code where the CLR is constrained from injecting any system-generated errors. At the same time, your application should handle exceptions it expects to see (for example, OutOfMemoryException, in case new objects are created).

In addition to CERs, Whidbey provides reliability contracts. These contracts can be used to annotate the methods with their guarantees and requirements with respect to reliability. Using these contracts, it is possible to compose reliable execution out of components written by different authors, which is necessary for building reliable applications that make use of framework services.

Whidbey seems to be doing a much better job at ensuring that finalization and garbage collection will be executed properly in high-load situations. This makes the platform itself and .NET CLR an even better contender in the enterprise space that is mostly occupied by Solaris/Java bundle and mainframe systems.



 
 
>>> More Using Microsoft Visual Studio Articles          >>> More By Max Loukianov