Hi friends, I hope all of you are fine. In this series of articles we will try to learn a few general concepts of garbage collection in C#. In a future article we will dig in dipper and try to learn a few behind-the-scenes concepts.
In the context of garbage collection (I hope you are familiar with the term already and are familiar with the basics of it) in C# is the subject of .NET support of automatic garbage collection. So the conclusion is "Being a .NET developer we should not be concered with memory management and the freeing of memory properly allocated by an object". And here the misconceptions begin.
Friend, I am not accepting that .NET does not support automatic garbage collection, it does support it and GC.collect() exists. And with due respect to GC.collect() I am making the statement "Don't call/use GC.Collect() here and there and frequently". Please don't ask me why right now. To provide the answer I need to introduce another article, in a future article we will talk about it. For now I will provide a one-line answer. GC.collect() collects all unused objects from all generations and it's a very resource-intensive process.
OK, let's return to the topic of garbage collection. If you are from a C/C++ background then you might be aware of destructors used to free resources created by a constructor (as we read from the book).
Let me tell you my little experience. One day in a language practical lab in our college there was a practical session of Destructors. A friend sitting beside me asked me, "Hey Sourav, Look at my program. I have defined a destructor but it's not executing". I checked his program (yes, he has defined a destructor with proper syntax) and found he did not a create scope within the main when he is creating the object. As we know, the key concept of a destructor in C++ is "when the object goes out of scope and is no longer in use, destructors run and clear the resources".
But the same concept is not true in C#. Let's check whether it works or not. In the following I have written a small code snippet to do the same and have created an object within the scope in the Main() function.
using System;
using System.Collections;
using System.Globalization;
using System.Data.SqlClient;
using System.Data;
namespace Test1
{
public class Garbage
{
public Garbage()
{
Console.WriteLine("Reserve memory");
}
~Garbage()
{
Console.WriteLine("Free memory");
}
}
class Program
{
static void Main(string[] args)
{
{ //Genearte scope here
Garbage g = new Garbage();
g = null;
}
Console.ReadLine();
}
}
}
Here we are clearly seeing, the destructor is not running in spite of creating scope. From here the concept of garbage collection begins. In C#, the destructor does not run when the object goes out of scope.
Then, how we will free memory when we finish work with object?
The question is very good and the very bad solution is to use GC.Collect(). If you are reading from the first line then I think already you know why the solution is bad. Any the way to clear resources when we are done with an object using GC.collect(). Have a look at the following code:
using System;
using System.Collections;
using System.Globalization;
using System.Data.SqlClient;
using System.Data;
namespace Test1
{
public class Garbage
{
public Garbage()
{
Console.WriteLine("Reserve memory");
}
~Garbage()
{
Console.WriteLine("Free memory");
}
}
class Program
{
static void Main(string[] args)
{
{
Garbage g = new Garbage();
g = null;
GC.Collect();
}
Console.ReadLine();
}
}
}
Now , we can see that the destructor is being executed. But one thing we need to keep in mind. The Garbage Collector can collect those objects that are null and no longer referenced anywhere. To understand the concept in practice, have a look at the following code.
Garbage Collector can collect only unused object
Let's prove this concept here. In the following example we will try to collect an object that is not free:
using System;
using System.Collections;
using System.Globalization;
using System.Data.SqlClient;
using System.Data;
namespace Test1
{
public class Garbage
{
public string Name = null;
public Garbage()
{
Console.WriteLine("Reserve memory");
}
~Garbage()
{
Console.WriteLine("Free memory");
}
}
class Program
{
static void Main(string[] args)
{
{





Giulio GmailPosted Aug 14, 2013, 7:28 PM
Just now I've found the hidden SQLiteDateReader I had to close and dispose before closing its command. Everything works like a charm now and no lock remains on the db after closing/disposing the connection even without the need of forcing a GC.collect :-)
Giulio GmailPosted Aug 14, 2013, 4:02 PM
I have a program with a dependency injection framework working on a sqlite connection where I can not leverage on the using structure. So I need to explicitly open and finally close the connection. I also try to dispose any connection objects, commands, readers But the db remains locked until I close the app. I'm forced to use a GC.collect to magically fix the issue! Please express your comment: sqlite bug? an hidden app object not disposed yet? or a GC.collect really needed despite saying! ;-)
Sam HobbsPosted Aug 12, 2013, 12:35 PM
Perhaps I misunderstand what you are saying, but the destructor is being executed, even in the first sample. If you execute the sample without the debugger (such as using Ctrl-F5) then you will get the "Free memory" message. If you execute it with the debugger and put a breakpoint on the destructor then you will see that the destructor is called. Since the scope cleanup of Main occurs after Main finishes, the call to Console.ReadLine is too early for you to see the "Free memory" message.
Sandeep Singh ShekhawatPosted Aug 12, 2013, 5:02 AM
good one Sourav!! I have few quetions..1. How to object marks from one generation to another generation? 2. If I have more then 50 objects in gen0,gen1 or may be gen2 the GC check to all the object? 3. If object remove from gen0 then it would also check for gen1?. 4. How to remove object from gen2 that is more stable comparsion gen0 and gen1?