The .NET Compact Framework, just like the full .NET framework, features a garbage collector that automatically runs on its own to free up unused memory to the operating system. The garbage collector runs when any of the following conditions are met:
• The application is moved to the background:
When an application is moved to the background, a garbage collection is run.
• After an allocation threshold:
A garbage collection is automatically initiated after 1 MB of memory is allocated since the last garbage collection.
You can call the GC.collect() function in managed code to force a garbage collection.
• Out-of-memory condition:
When the system fails to allocate or reallocate memory, a garbage collection is automatically initiated by the .NET Compact Framework to attempt to free up more memory.
The following diagram describes the lifecycle of an object and how it is eventually collected by the garbage collector:
1. When an object is created and memory is allocated for it, the object is considered a live object.
2. When the object can no longer be accessed by code (for example, when there are no more references to the object), the object is considered no longer in use and is eligible for finalization.
3. The garbage collector runs based on any of the four conditions mentioned earlier being met.
4. The garbage collector brings all threads to a "safe point"—bringing all threads to a state where they cannot modify the Garbage Collection (GC) heap further in any way.
5. All live objects that are reachable by the garbage collector are marked.
6. Among those objects that are not reachable (unmarked objects), the ones that do not have finalizers are freed by the garbage collector. The ones that do have finalizers are placed in a finalization queue.
7. The garbage collector runs the finalizers on all objects in the finalization queue. After the unused objects are freed, the collection is considered complete, and all threads are allowed to resume.
Garbage collection is a somewhat expensive process—it needs to suspend threads, mark live objects, and so on. Forcing a Gc.collect() call frequently to free up memory is, therefore, not a good practice and may even lead to a significant decrease in performance. If your application runs out of memory more often than usual, you should ensure that your objects have been properly disposed (call the .Dispose() method if it is available in the object). The garbage collector should be left to run automatically.
Was this article helpful?