I have got a simple ConsoleProgram which is creating a list of 80 IDisposable objects. This object hold two System.Threading.ManualResetEvent which are closed in the Dispose() method. Please consider the code:
public class Program
{
private static void Main(string[] args)
{
Console.ReadLine();
Test(80);
Console.WriteLine("end.");
Console.ReadLine();
}
private static void Test(int c)
{
Console.WriteLine("Test start.");
List<TestObject> list = new List<TestObject>();
for (int i = 0; i < c; i++)
list.Add(new TestObject());
Console.WriteLine("End of adding. Added: {0} items.", c);
Console.ReadLine();
foreach (TestObject obj in list)
obj.Dispose();
list = null;
Console.WriteLine("Dispose end.");
}
public class TestObject : IDisposable
{
public ManualResetEvent mr1 = new ManualResetEvent(true);
public ManualResetEvent mr2 = new ManualResetEvent(false);
public void Dispose()
{
mr1.Close();
mr2.Close();
}
}
}
I have tested my program in case of consumed memory and memory leaks. I supposed that consumed memory will increase after creating all list objects, but it will decrease after calling the Dispose() method and setting null value to the list object. Unfortunately I have observer different behaviour. Please consider following result of my test:
- Program starts (nothing created). WorkingSet = 6.700K
- List of 80 objects was created. WorkingSet = 7.160K (memory grow: 460K)
- Program called the
Dispose()method an setnullto list object. WorkingSet = 7.164K (memory grow form last point: 4K) - Program is hanging for more than 20 minutes. WorkingSet = 7.296K (memory grow from last point: 105K, memory grow from the beginning: 596K)
- Program was closed.
I am really confused about the point 3 and 4. Why the memory was not released? I think that this is a memory leak, because the total memory grow was equal to 596K and it was never released.
Thank you very much for any answer.
PS. Changing the number of object, for example to 9000, cause a memory growth of more than 2MB.
PS2. At the end of my program I am calling GC.Collect() to force the clean-up. But after that amount of used memory is still the same and it is not decreasing – I am confused.
Calling
Dispose()and setting a value to null does not free the memory up immediately. Your memory should be released when the Garbage Collector next runs, but this time is not deterministic. Typically, it will happen when the application is under memory pressure, usually as a result of object creation requesting more memory. Without that pressure, and with the application idle, the GC might never collect your memory.In short, this is not a memory leak.