我有一个简单的ConsoleProgram,它创建了一个包含80个IDisposable对象的列表。该对象包含两个System.Threading.ManualResetEvent
,它们在Dispose()
方法中关闭。请考虑代码:
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();
}
}
}
我已经测试了我的程序,以免耗尽内存和内存泄漏。我认为在创建所有列表对象后消耗的内存会增加,但在调用Dispose()
方法并将null
值设置为列表对象后,它将减少。不幸的是,我有观察者不同的行为。请考虑以下测试结果:
Dispose()
方法称为集合null
以列出对象。 WorkingSet = 7.164K(内存从最后一点增长:4K)我对第3点和第4点感到困惑。为什么没有释放内存?我认为这是一个内存泄漏,因为总内存增长等于596K并且它从未被释放。
非常感谢您的回答。
PS。将对象数量更改为9000会导致内存增长超过2MB。
PS2。在我的计划结束时,我打电话给GC.Collect()
强制进行清理。但是,在使用的内存量仍然相同而且没有减少之后 - 我很困惑。
答案 0 :(得分:5)
调用Dispose()
并将值设置为null会使不立即释放内存。垃圾收集器下次运行时应释放您的内存,但这次不是确定性的。通常,当应用程序处于内存压力下时,通常会由于对象创建请求更多内存而发生。如果没有这种压力,并且应用程序空闲,GC可能永远不会收集你的记忆。
简而言之,这不是内存泄漏。