Index
- Introduction
- How Garbage Collector works
- Unmanaged resources
- Weak references
- References
Introduction
This post is part of a series of post to help you prepare the MCSD certification, particularly the certification exam 70-483, based on the book:You will find all the code available in the following GitHub repository. Lets talk a little bit about threads and how they work using a .Net development environment.
How Garbage Collector works
Within your applications you will find plenty of different types of elements. Some of them are regular strings or numbers, which are called managed resources. Some others, like connections to databases or object references to files are called unmanaged resources. .Net knows exactly how to handle the first type and when to get rid of them but with unmanaged resources is other story...
There are two places in your CPU where the CLR stores these elements: the heap and the stack. Think about the stack as what's executing in your code and the heap who keeps track of your objects. Value types can go on both and for each object in the heap there's always a reference in the stack. The stack is cleared automatically at the end of each method but the heap is managed by the Garbage Collector.
The GC works with a mark and compact algorithm which checks if an item in the heap is still referenced by a method / local variable or register and takes all those objects and moves them together. During the process, all is frozen and references to the objects are fixed. This happens only if there's not enough memory and the usage of the application is low.
The process only focus on Generation 0 elements, which are elements who survived to a previous clean up and are likely to be removed in the next one. Next generations are touched only if the memory released by Gen0 is not enough.
Unmanaged resources
In order to vanish these unmanaged resources .Net provides a couple of mechanism like: finalizers and IDisposable interface. Finalizers are called only when the GC occurs and they are similar to constructors but adding a tilde (~) as a prefix name, and including your code to release your resources. You can trigger the GC clean manually by calling GC.Collect(); but this is not a recommended practice. Bear in mind that the finalizers increase the life of your objects just because those objects will get an special treatment by being added into the finalization queue. This delays GC for types that have a finalizer.
In some cases you don't want to depend on the GC to release your resources, actually, you should act proactively doing the cleaning by implementing the IDisposable interface which contains only a method: Dispose();. .Net also provides an special wrapper (using) for your unmanaged resources which implement this interface:
This using is the same as having a try/catch/finally statement where you call the Dispose() method within the finally case, but all in one expression. See here below an example of how to implement this interface:
As you can see, the Dispose method with the parameter is a way to know if the dispose has been triggered explicitly or from the finalizer. If the finalizer made the call, you don't have to perform anything because the Stream already comes with a finalizer in it which the GC will run. If the call is explicitly, then close the FileStream. Bear in mind this can be called several times and you need to perform a defending code strategy.
The regular Dispose() method calls GC.SuppressFinalize(this); to make sure that the object is removed from the finalization list that the garbage collector is keeping track of.
Weak references
Imagine you are retrieving a large list of elements from a database which implies a large amount of memory consume. You can't store this information forever, but you might want to access it in the future in case the GC has not removed it yet. In this cases, the type WeakReference can be used.
These references doesn't hold a real reference to an element on the heap so they can't be removed by the GC. If garbage collection has not occurred yet, you can still access the object through your WeakReference type.
0 comments:
Post a Comment