Страницы

Поиск по вопросам

четверг, 19 декабря 2019 г.

Освобождается ли память, выделенная под переменную ссылочного типа, которая объявлена внутри метода?

#c_sharp #net #сборщик_мусора


Допустим, имеется метод внутри класса:

public ICollection GetData()
{
    ICollection rezult;
    var tempCollection = context.Get();
    //doing some stuff;
    return rezult;
}


Как ни крути, мне в коде нужна эта временная переменная. Вопрос состоит в том, нужно
ли "занулять" эту переменную (tempCollection = null;), чтобы GC при сборке мусора понял,
что она уже не нужна, или же это и так будет понятно, посколько она объявлена внутри
метода?
    


Ответы

Ответ 1



При завершении метода все его локальные переменные пропадают (если только не были захвачены замыканием). Отдельно занулять их не нужно.

Ответ 2



Объект, на который ссылается tempCollection, превращается в мусор сразу же после последнего упоминания tempCollection в теле метода - т.е. иногда задолго до того, как метод вернет управление. GC собирает объекты после того, как они станут недостижимыми - т.е. после того, как их, прямо или косвенно, нельзя будет увидеть из т.н. корней - статических полей, локальных переменных и еще пары специфических мест. Как только объект становится недостижим - GC может его спокойно убить. Предположим что ваш метод выгдядит вот так: public ICollection GetData() { ICollection rezult; var tempCollection = context.Get(); // doing some stuff // последнее упоминание tempCollection в методе: var something = tempCollection.SomeProp; // doing some more stuff; return rezult; } Локальная переменная tempCollection упоминается только в верхней половине метода. Ниже этой строчки код никак не может получить доступ к ее содержимому. Так что GC вполне справедливо не считает ее корнем в нижней половине метода. Учитывая это, добавление дополнительного упоминания tempCollection в коде (пусть даже и в виде tempCollection = null) не сократит, а наоборот, чуть-чуть продлит время его жизни. Стоит отметить, что при сборке в Debug, в отличии от Release, JIT заботится о вашем удобстве, и продлевает область жизни tempCollection до конца области видимости (т.е. до конца метода). Делает он это исключительно из соображений удобства при отладке - чтобы вы могли просмотреть значение tempCollection даже на последней строчке метода.

Комментариев нет:

Отправить комментарий