Может ли соответствующий компилятор C # оптимизировать локальную (но неиспользуемую) переменную, если это единственная надежная ссылка на объект? - PullRequest
11 голосов
/ 30 апреля 2010

См. Также следующие ресурсы:


Другими словами:

Может ли объект, на который ссылается местный переменная должна быть исправлена ​​до переменная выходит из области видимости (например, потому что переменная назначена, но затем не используется снова), или это объект гарантированно не подходит для сборка мусора до переменной выходит за рамки?

Позвольте мне объяснить:


void Case_1()
{
    var weakRef = new WeakReference(new object());

    GC.Collect();  // <-- doesn't have to be an explicit call; just assume that
                   //     garbage collection would occur at this point.

    if (weakRef.IsAlive) ...
}

В этом примере кода я, очевидно, должен планировать возможность того, что new'ed object будет возвращен сборщиком мусора; следовательно, оператор if.

(Обратите внимание, что я использую weakRef с единственной целью проверки, если новый 'object все еще рядом.)


void Case_2()
{
    var unusedLocalVar = new object();
    var weakRef = new WeakReference(unusedLocalVar);

    GC.Collect();  // <-- doesn't have to be an explicit call; just assume that
                   //     garbage collection would occur at this point.

    Debug.Assert(weakRef.IsAlive);
}

Основное изменение в этом примере кода по сравнению с предыдущим состоит в том, что на new'ed object строго ссылается локальная переменная (unusedLocalVar). Однако эта переменная больше не используется после создания слабой ссылки (weakRef).


Вопрос: Соответствующий компилятор C # позволяет оптимизировать первые две строки Case_2 в строки Case_1, если он видит, что unusedLocalVar используется только в одном месте, а именно как аргумент для конструктора WeakReference? есть ли вероятность, что утверждение в Case_2 может когда-нибудь потерпеть неудачу?

Ответы [ 3 ]

11 голосов
/ 30 апреля 2010

Неважно, что делает компилятор C # - JITter / GC разрешено очищать локальные ссылки, когда они больше не существуют в теле метода. Посмотрите документы для GC.KeepAlive

Кроме того, это представление PowerPoint , особенно начиная со слайда 30, помогает объяснить, на что способен JIT / GC.

3 голосов
/ 08 января 2011

Хотя на мой вопрос был дан ответ, я подумал, что опубликую соответствующую информацию, которую я только что нашел, в статье блога MSDN "WP7: когда GC считает локальную переменную мусором" 1003 * Абхинаб

[T] спецификация ECMA (ECMA 334, раздел 10.9) [& hellip;] сообщает

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

Это говорит само за себя. В упомянутой статье также говорится, что .NET Framework (по крайней мере, в режиме Release) будет выполнять интеллектуальный анализ и освобождать такие объекты, в то время как .NET Compact Framework не будет (по соображениям производительности).

0 голосов
/ 06 января 2013

Разрешено ли соответствующему компилятору C # оптимизировать первые две строки Case_2 в строки Case_1, если он видит, что unusedLocalVar используется только в одном месте, а именно в качестве аргумента для конструктора WeakReference?

Два определения эквивалентны, поэтому переход от одного к другому не является «оптимизацией», поскольку ни одно из них не является более эффективным.

т.е. есть ли вероятность того, что утверждение в Case_2 может когда-нибудь потерпеть неудачу?

Да. Производственный компилятор вряд ли сохранит ссылку излишне, поэтому она будет удалена, GC не будет рассматривать ее как глобальный корень и будет собирать этот объект.

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

...