简体   繁体   English

“readonly”(C#)是否会减少内存使用量?

[英]Does “readonly” (C#) reduce memory usage?

In C#, does setting a field as readonly reduce memory usage? 在C#中,将字段设置为readonly会减少内存使用量吗?

ie

DBRepository _db = new DBRepository();

vs VS

readonly DBRepository _db = new DBRepository();

Just curious. 只是好奇。 Thanks. 谢谢。

No. 没有。

It means you can't assign to it except at the declaration point or in a constructor. 这意味着除了在声明点或构造函数中,您无法分配它。 You also can't pass it as a ref or out parameter to a method. 您也不能将它作为refout参数传递给方法。

Edit: based on the comment below. 编辑:基于以下评论。 The following field is readonly because you want callers to have direct read access to string.Empty , but you don't want them to set it to something else. 以下字段是readonly因为您希望调用者具有对string.Empty直接读取权限,但您不希望它们将其设置为其他字段。

public sealed class String
{
    public static readonly string Empty = "";
}

Also, sometimes when I have a List<> or Dictionary<> as a field in a class, I'll declare it readonly to indicate that I want to work with its members (even Add and Remove items, etc.) but I never want to actually assign a different List or Dictionary object to it. 此外,有时当我将List<>Dictionary<>作为类中的字段时,我将声明它readonly以表明我想要使用其成员(甚至添加和删除项目等)但我从来没有想要实际为其分配不同的List或Dictionary对象。

One more edit: Make sure you read about the deprecated Path.InvalidPathChars field (in the remarks section) to show a serious problem that can happen when you don't understand what readonly is and is not. 还有一个编辑:确保您阅读了已弃用的Path.InvalidPathChars字段(在备注部分中),以显示当您不了解readonly是什么时可能发生的严重问题。

No. readonly and const basically serve the same purpose: to prevent assignments to the values at runtime. 编号readonlyconst基本上用于相同的目的:防止在运行时赋值。 However, they have semantically different uses. 但是,它们具有语义上不同的用途。

readonly versus const readonly与const

A const field is evaluated at compile time and can only be initialized at declaration, while a readonly field is evaluated at run time and can be initialized both in constructors and at declaration site. const字段在编译时计算,只能在声明时初始化,而readonly字段在运行时计算,并且可以在构造函数和声明站点初始化。

Also, a const field value is stored as part of the metadata and so is initialized in the relevant constructor of the class that declared it while readonly fields will have to be computed at runtime. 此外, const字段值存储为元数据的一部分,因此在声明它的类的相关构造函数中初始化,而readonly字段必须在运行时计算。

YES! 是!

Yes? 是? Yes! 是! How? 怎么样? Simple. 简单。 A read-only field cannot get a new value so you can't create a second DBRepository and assign it to this field. 只读字段无法获取新值,因此您无法创建第二个DBRepository并将其分配给此字段。 If it's not read-only then you could write code which will re-assign a new value to this field. 如果它不是只读的,那么您可以编写代码,该代码将为该字段重新分配新值。 And during the time between the reassignment and the time for the garbage collector to clear your old value, you will have a bit more memory in use. 在重新分配和垃圾收集器清除旧值之间的时间内,您将使用更多的内存。 Furthermore, if cleanup of the DBRepository has a memory leak, then reassigning new values to this field will cause multiple memory leaks. 此外,如果DBRepository的清理有内存泄漏,则将新值重新分配给此字段将导致多个内存泄漏。

A situation where such a memory leak could occur is this: 1) You assign a value to _db. 可能发生此类内存泄漏的情况如下:1)您为_db分配值。 2) You assign the value of _db to another field. 2)您将_db的值分配给另一个字段。 3) You reassign a new value to _db. 3)您将新值重新分配给_db。 At this moment you will have two DBRepository objects in memory because the old object is still referenced to from another object. 此时,内存中将有两个DBRepository对象,因为旧对象仍然是从另一个对象引用的。 Thus the old object won't be freed until the second field releases it. 因此,在第二个字段释放旧对象之前,不会释放旧对象。

But this is very nitpicky and quite rare. 但这非常挑剔而且非常罕见。 The answer "No" is more appropriate. 答案“不”更合适。 Don't use "ReadOnly" to save memory because you'd be using it for the wrong reason. 不要使用“ReadOnly”来节省内存,因为你出于错误的原因使用它。 Use "ReadOnly" to make sure others won't reassign a value to this field. 使用“ReadOnly”确保其他人不会将值重新分配给此字段。 (Basically, I'm saying that it can reduce memory usage...) (基本上,我说它可以减少内存使用量......)

readonly is useful in the case you want to use an object as an key. readonly在您想要将对象用作键时非常有用。 This key shouldn't change, otherwise you cannot access what it gives access to. 此密钥不应更改,否则您无法访问它提供的访问权限。

For instance; 例如; 1) with events in an ASP.NET site, you can use the Events collection in a Control. 1)使用ASP.NET站点中的事件,您可以使用Control中的Events集合。 In your control you would keep a readonly object field to refer to the event handlers in the collection. 在您的控件中,您将保留一个只读对象字段来引用集合中的事件处理程序。 2) In multi-treading, you might need to synchronize access. 2)在多线程中,您可能需要同步访问。 This can be done to combine the lock statement with a readonly object on which to lock. 可以这样做以将lock语句与要锁定的只读对象组合。

The answer No is written from the perspective of a good performance focused coder who already knows all the tricks and traps eg.: 答案否是从一个已经知道所有技巧和陷阱的优秀表现聚焦编码器的角度写的,例如:

  1. No LINQ in tight loops. 紧密循环中没有LINQ。 Really. 真。 None. 没有。 Ever. 永远。
  2. Cast your enums to ints before comparison 在比较之前将您的枚举投射到整数
  3. Beware of value type structs 注意价值类型结构
  4. 'new' is the new Grue 'new'是新的Grue
  5. CLRProfiler is your friend CLRProfiler是你的朋友
  6. Other profilers will put variable construction time into weird places 其他剖析器将可变的施工时间放入奇怪的地方

The answer Yes is very relevant to a coder not aware of the pitfalls of the design of C#, or one who has swallowed the "Profiling is evil" coolade. 答案是和一个没有意识到C#设计陷阱的编码员非常相关,或者是一个吞下“剖析是邪恶的”coolade的人。

I initialize a lot (maybe even a LOT) of matrices and arrays in our code. 我在代码中初始化了很多(甚至很多)矩阵和数组。 I have noticed that lazy initialization with: if (variable == null) // variable = new Variable() 我注意到懒惰初始化:if(variable == null)// variable = new Variable()

seems less performant than constructing up front. 似乎不如建造前线那么高效。 Since readonly forces you to construct in the constructor you get the benefits of data localization in memory and prevents you from doing other disasterous 'build and replace at runtime' things. 由于readonly强制您在构造函数中构造,因此您可以获得内存中数据本地化的好处,并防止您在运行时进行其他灾难性的“构建和替换”操作。 C# can choke horribly on the garbage collector. C#可以在垃圾收集器上狠狠地窒息。

C# allows us to very easily write terribly memory innefficient code. C#允许我们非常容易地编写非常有效的代码。 malloc was a way to force us to think about (de)allocation. malloc是一种迫使我们思考(de)分配的方法。 In the same way, readonly forces us to think about it. 以同样的方式,readonly迫使我们思考它。

Run CLRProfiler, see for yourself how much memory spam you make. 运行CLRProfiler,自己查看你发送了多少内存垃圾邮件。 If you've been writing HPC without almost superhuman discipline, the chances are you're spamming the heap and readonly can help prevent you from doing that. 如果你一直在写HPC而没有几乎超人的纪律,那么你很可能是垃圾邮件堆,而readonly可以帮助阻止你这样做。

That said, if you're not writing HPC code then premature optimization is the root of all learning about machine architecture. 也就是说,如果您不编写HPC代码,那么过早优化是所有有关机器架构学习的根本。 Oh, no, wait... I meant evil, per the standard doctrine. 哦,不,等等......根据标准学说,我的意思是邪恶。 All hail the standard doctrine. 所有人都欢呼标准学说。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM