readonly修饰符对垃圾收集器有影响吗?

den*_*123 5 c# garbage-collection readonly

readonly修饰符是否可能影响垃圾收集器的工作?对于值类型,参考类型?

Jar*_*Par 6

不,不是的.GC通过回收内存来查找无法从任何有根对象访问的对象.readonly修饰符对此过程没有影响.除了具有少量只读字段的两个对象图之外,将以相同的方式收集两个对象图.


Cod*_*aos 1

我不明白为什么它会影响正常使用的 GC。这只是一个领域。GC 仅遵循引用类型字段(或结构字段中包含的引用)。

您也许能够构建影响 GC 的人为场景(可能滥用只读字段的防御副本),但正常使用时不会发生这种情况。

当然,您不能在方法中将该字段设置为 null,Dispose如果您希望为 GC 准备昂贵的自有对象,同时某些对象保存对包含对象的引用,则这种方法可能很有用。

程序由于以下原因而改变行为的邪恶样本readonly

该程序表明,仅将字段从非只读更改为只读就可以防止收集具有其他相同代码的对象。它滥用在方法调用时复制只读字段以将可写结构中的 Obj 字段设置为 null 并将引用保留在只读结构中。由于它可以防止引用变为空,因此可以防止收集对象。
但这当然不会影响 GC 本身。相反,滥用只读语义来创建具有只读功能和不具有只读功能的不同对象图。所以贾里德的说法仍然完全正确。

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
}
Run Code Online (Sandbox Code Playgroud)