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

发布于 2024-10-04 18:15:39 字数 49 浏览 0 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

暮光沉寂 2024-10-11 18:15:39

不,事实并非如此。 GC 的工作原理是回收无法从任何根对象访问的对象的内存。 readonly 修饰符对此过程没有影响。将以相同的方式收集两个对象图,除了一个对象图具有一些只读字段之外,这两个对象图是相同的。

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.

初心未许 2024-10-11 18:15:39

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

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

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

由于只读而改变程序行为的邪恶示例

该程序表明,仅将字段从非只读更改为只读就可以阻止使用其他相同代码收集对象。它滥用在方法调用时复制只读字段,以将可写结构中的 Obj 字段设置为 null 并将引用保留在只读结构中。由于它可以防止引用变为 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
}

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
}
眼眸里的快感 2024-10-11 18:15:39

readonly 是一项 C# 功能。 GC 是 CLI 功能。因此,它根本不能影响GC。。

readonly is a C# feature. The GC is a CLI feature. Therefore, it simply cannot influence the GC at all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文