简单的ConsoleProgram与IDisposable - 没有内存减少 - 我们有泄漏?

时间:2012-08-08 09:29:28

标签: c# .net memory-leaks idisposable

我有一个简单的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值设置为列表对象后,它将减少。不幸的是,我有观察者不同的行为。请考虑以下测试结果:

  1. 程序启动(没有创建)。 WorkingSet = 6.700K
  2. 创建了80个对象的列表。 WorkingSet = 7.160K(内存增长:460K)
  3. 程序将Dispose()方法称为集合null以列出对象。 WorkingSet = 7.164K(内存从最后一点增长:4K)
  4. 节目暂停超过20分钟。 WorkingSet = 7.296K(内存从最后一点增长:105K,内存从头开始增长:596K)
  5. 程序已关闭。
  6. 我对第3点和第4点感到困惑。为什么没有释放内存?我认为这是一个内存泄漏,因为总内存增长等于596K并且它从未被释放。

    非常感谢您的回答。

    PS。将对象数量更改为9000会导致内存增长超过2MB。

    PS2。在我的计划结束时,我打电话给GC.Collect()强制进行清理。但是,在使用的内存量仍然相同而且没有减少之后 - 我很困惑。

1 个答案:

答案 0 :(得分:5)

调用Dispose()并将值设置为null会使立即释放内存。垃圾收集器下次运行时应释放您的内存,但这次不是确定性的。通常,当应用程序处于内存压力下时,通常会由于对象创建请求更多内存而发生。如果没有这种压力,并且应用程序空闲,GC可能永远不会收集你的记忆。

简而言之,这不是内存泄漏。