Информация об изменениях

Сообщение Re[14]: Только что с интервью... от 29.03.2017 7:58

Изменено 29.03.2017 9:20 fmiracle

Re[14]: Только что с интервью...
Здравствуйте, IT, Вы писали:

IT>Будет ли разным генерируемый код для следующего?

IT>
IT>void Foo()
IT>{
IT>    {
IT>        object o = new object();
IT>    }
IT>}

IT>void Foo()
IT>{
IT>    object o = new object();

IT>    {
IT>    }
IT>}

IT>void Foo()
IT>{
IT>    object o;

IT>    {
IT>        o = new object();
IT>    }
IT>}
IT>

IT>Я не уверен.

Если проверить поведение экспериментально, то видно, что в релиз-сборке, объект, на который ссылается переменная, может быть собран сборщиком мусора после того, как переменная уже не используется. Неважно, внутри блока или нет. Если переменная объявлена внутри блока, то это просто точная уверенность, что дальше она уже не используется.

  вот такой пример на коленке
class Tst
        {
            public string Name { get; set; }
            public Tst(string name)
            {
                Name = name;
            }

            ~Tst()
            {
                Console.WriteLine( $"finalizer called for {Name}" );
            }

            public override string ToString()
            {
                return Name;
            }
        }

        static void Main( string[] args )
        {
            object o1;
            var o2 = new Tst("o2");
            var o4 = new Tst( "o4" );
            {
                var o3 = new Tst("o3");
                o1 = new Tst("o1");
            }
            Console.WriteLine( "init done" );
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Console.WriteLine( "method almost complete" );
            Console.WriteLine( "last use of {0}", o4 );
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Console.WriteLine( "method complete" );
        }

вывод в Релизе:

init done
finalizer called for o1
finalizer called for o3
finalizer called for o2
method almost complete
last use of o4
finalizer called for o4
method complete

Т.е. первые 3 объекта успешно собираются сборщиком мусора еще до окончания метода. И при этом неважно, как они объявлены — значение имеет лишь, что на момент сборки мусора CLR видит, что далее эти переменные не используются.

В дебаге, кстати, вывод другой, там сборка всех объектов только по окончании метода:

init done
method almost complete
last use of o4
method complete
finalizer called for o1
finalizer called for o3
finalizer called for o4
finalizer called for o2

Re[14]: Только что с интервью...
Здравствуйте, IT, Вы писали:

IT>Будет ли разным генерируемый код для следующего?

IT>
IT>void Foo()
IT>{
IT>    {
IT>        object o = new object();
IT>    }
IT>}

IT>void Foo()
IT>{
IT>    object o = new object();

IT>    {
IT>    }
IT>}

IT>void Foo()
IT>{
IT>    object o;

IT>    {
IT>        o = new object();
IT>    }
IT>}
IT>

IT>Я не уверен.

Если проверить поведение экспериментально, то видно, что в релиз-сборке, объект, на который ссылается переменная, может быть собран сборщиком мусора после того, как переменная уже не используется. Неважно, внутри блока или нет. Если переменная объявлена внутри блока, то это просто точная уверенность, что дальше она уже не используется.

  вот такой пример на коленке
class Tst
        {
            public string Name { get; set; }
            public Tst(string name)
            {
                Name = name;
            }

            ~Tst()
            {
                Console.WriteLine( $"finalizer called for {Name}" );
            }

            public override string ToString()
            {
                return Name;
            }
        }

        static void Main( string[] args )
        {
            object o1;
            var o2 = new Tst("o2");
            var o4 = new Tst( "o4" );
            {
                var o3 = new Tst("o3");
                o1 = new Tst("o1");
            }
            Console.WriteLine( "init done" );
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Console.WriteLine( "method almost complete" );
            Console.WriteLine( "last use of {0}", o4 );
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Console.WriteLine( "method complete" );
        }

вывод в Релизе:

init done
finalizer called for o1
finalizer called for o3
finalizer called for o2
method almost complete
last use of o4
finalizer called for o4
method complete

Т.е. первые 3 объекта успешно собираются сборщиком мусора еще до окончания метода. И при этом неважно, как они объявлены — значение имеет лишь, что на момент сборки мусора CLR видит, что далее эти переменные не используются.

В дебаге, кстати, вывод другой, там никакие локальные объекты не собираются до окончания метода:

init done
method almost complete
last use of o4
method complete
finalizer called for o1
finalizer called for o3
finalizer called for o4
finalizer called for o2