Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does readonly modifier influence on Garbage collector?

Is it possible that readonly modifier influences on Garbage collector work? For value type, for reference type?

like image 931
den123 Avatar asked Nov 23 '10 18:11

den123


2 Answers

No it does not. The GC works by reclaiming memory for objects which are not reachable from any of the rooted objects. The readonly modifier has no impact on this process. Two objects graphs which were identical with the exception of one having a few readonly fields would be collected in the same fashion.

like image 57
JaredPar Avatar answered Sep 30 '22 15:09

JaredPar


I don't see why it should influence the GC with normal use. It's just a field. And the GC simply follows reference type fields(or references contained in struct fields).

You might be able to construct artificial scenarios where it influences the GC(perhaps abusing defensive copies of the readonly field), but it won't occur with normal usage.

And of course you can't set the field to null in a method like Dispose which might be useful if you want to have expensive owned objects ready for GC while something holds a reference to the containing object.

Evil sample of a program changing behavior due to readonly

This program shows that just changing a field from not readonly to readonly can prevent collection of an object with otherwise identical code. It abuses that a readonly field gets copied on method invocation to set the Obj field null in the writable struct and keep the reference in the readonly struct. Since it prevents the reference from becoming null it prevents the object from being collected.
But of course this doesn't influence the GC itself. But instead abuses the semantics of readonly to create a different object graph with readonly than without. So Jared's statement is still completely true.

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
}
like image 26
CodesInChaos Avatar answered Sep 30 '22 15:09

CodesInChaos