Влияет ли модификатор readonly на сборщик мусора? - PullRequest
5 голосов
/ 23 ноября 2010

Возможно ли, что модификатор readonly влияет на работу сборщика мусора?Для типа значения, для ссылочного типа?

Ответы [ 3 ]

6 голосов
/ 23 ноября 2010

Нет, это не так. GC работает, восстанавливая память для объектов, которые недоступны ни одному из корневых объектов. Модификатор readonly не влияет на этот процесс. Два графов объектов, которые были идентичны, за исключением одного, имеющего несколько полей только для чтения, будут собираться одинаково.

1 голос
/ 23 ноября 2010

Не понимаю, почему это должно влиять на ГХ при нормальном использовании. Это просто поле. А GC просто следует полям ссылочного типа (или ссылкам, содержащимся в полях структуры).

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

И, конечно, вы не можете установить для поля значение null в методе, подобном Dispose, который может быть полезен, если вы хотите иметь дорогие собственные объекты, готовые для GC, в то время как что-то содержит ссылку на содержащий объект.

Злой образец изменения программы из-за readonly

Эта программа показывает, что простое изменение поля с не только для чтения на только для чтения может помешать сбору объекта с другим идентичным кодом. Он злоупотребляет тем, что поле readonly копируется при вызове метода, чтобы установить нулевое поле Obj в структуре с возможностью записи и сохранить ссылку в структуре readonly. Так как он предотвращает обнуление ссылки, он предотвращает сбор объекта.
Но, конечно, это не влияет на сам GC. Но вместо этого использует семантику readonly для создания другого графа объектов с readonly, чем без него. Таким образом, утверждение Джареда все еще полностью верно.

struct EvilStruct
{
    public readonly object Obj;

 public void SetToNull()
 {
   this=new EvilStruct();
 }

 public EvilStruct(object obj)
 {
   Obj=obj;
 }
}

readonly EvilStruct s1=new EvilStruct(new object());
EvilStruct s2=new EvilStruct(new object());

void Main()
{
    s1.SetToNull();
 s2.SetToNull();
 s1.Obj.Dump();//An instance of System.Object
 s2.Obj.Dump();//null
 //now s1.Obj can't be collected, but what was once in s2.Obj can
}
0 голосов
/ 23 ноября 2010

readonly является функцией C #. GC является функцией CLI. Следовательно, он просто не может влиять на GC вообще .

...