计时器和垃圾收集

Timers and Garbage Collection

假设我有一个 class 像这样

class A
{
    private B _objB
    private Timer _timer; // Using System.Timers 

    public A(objB)
    {
        _objB = objB;
        _timer = new Timer();
        _timer.Interval = 1000;
        _timer.Elapsed += SomeEvent;
    }

    public void Begin()
    {
        _timer.start();
    }

    public void End()
    {
        _timer.Dispose();
    }

    public void SomeEvent (object sender, ElapsedEventArgs e)
    {
        if (_objB.Condition())
        {
            // do something
        }
        else 
        {
            _timer.Dispose();
        }
    }
}

现在在我的代码中的其他地方使用不同的 class 我这样做

public void SomeMethod(B objectB)
{
    A objA = new A(objectB);
    objA.Begin();
   // do other stuff
   // objA.End() can be called here but for this example it's not
}

我知道当我退出 SomeMethod() 的范围时,objA 将不会被垃圾回收,因为有一个持续触发的计时器事件。我不确定的是:

1) 在 SomeEvent 中,我遇到 else 条件并调用 _timer.Dispose(),这将停止触发更多事件,但这会告诉 GC 它可以清理计时器和 objA 吗?换句话说,我是否造成任何内存泄漏?

2) 是否存在任何可能导致异常的竞争条件?因此,如果我正在调用 _timer.Dispose() 并且以某种方式在队列中有另一个计时器事件,那么进入该事件会导致任何异常吗?

我只是不确定我是否进行了适量的清理以避免内存泄漏。

  1. 基本正确。当你dispose Timer的时候,ObjA就有资格被GC了。事实上,垃圾收集器将在下一个垃圾收集周期收集它。

请记住,它不会在符合 GC 条件后立即收集您的对象。垃圾收集器使用其启发式算法来触发垃圾收集。它仅在存在内存压力时发生。事实上当 Gen0 或 Large Object Heap 即将溢出时。

  1. 可能..看看here.

Callbacks can occur after the Dispose() method overload has been called, because the timer queues callbacks for execution by thread pool threads. You can use the Dispose(WaitHandle) method overload to wait until all callbacks have completed.