GC корни и локальные переменные - PullRequest
4 голосов
/ 07 декабря 2011

Просматривая документацию по таймеру , я наткнулся на следующий пример с этим комментарием:

    // Normally, the timer is declared at the class level,
    // so that it stays in scope as long as it is needed.
    // If the timer is declared in a long-running method,  
    // KeepAlive must be used to prevent the JIT compiler 
    // from allowing aggressive garbage collection to occur 
    // before the method ends. You can experiment with this
    // by commenting out the class-level declaration and 
    // uncommenting the declaration below; then uncomment
    // the GC.KeepAlive(aTimer) at the end of the method.
    //System.Timers.Timer aTimer;
    code in between
    // If the timer is declared in a long-running method, use
    // KeepAlive to prevent garbage collection from occurring
    // before the method ends.
    //GC.KeepAlive(aTimer);

Значит ли это, что GC в C # разрешено собирать локальные переменные, даже если это будет иметь побочные эффекты? Предположительно, потому что я не получаю доступ к таймеру после этого снова, GC может забрать его раньше?

Не уверен, что я фанат такой оптимизации, если я правильно понимаю (но тогда я, вероятно, нет;))

Ответы [ 2 ]

2 голосов
/ 07 декабря 2011

Да, GC может собирать локальную переменную до окончания области действия, как только после последнего использования переменной. Помещение GC.KeepAlive в конец метода гарантирует, что переменная будет «жива» до вызова KeepAlive.

C # является обязательным языком, поэтому GC не был разработан, чтобы знать что-либо о побочных эффектах.

1 голос
/ 07 декабря 2011

Насколько я понимаю, сборщик мусора помечает любую переменную или объект, который, по его мнению, больше не нужен в качестве кандидата на сборку мусора во время следующего цикла сбора мусора.Я не уверен, что понимаю конкретное приложение здесь, но я знаю, что есть случаи, когда сборщик мусора может пометить ресурс для сбора, когда он все еще необходим (но не появляется из-за способа написания кода).

Обычно во время методов объект или переменная остаются в области действия на время вызова метода, но если вызов метода длится дольше, чем время между циклами GC, GC может увидеть ваш объект Timer как находящийся вне областии пометить его для сбора.Добавление метода GC.KeepAlive заставляет GC ждать, пока метод не завершится, прежде чем воздействовать на объект Timer.

...