设定对象Null/没有什么后使用。净
-
08-06-2019 - |
题
你应该设置的所有对象 null
(Nothing
在VB.NET)一旦你完成了他们?
我的理解是,在。净至关重要的是处理任何实例的对象,实施 IDisposable
接口,以释放一些资源,尽管目仍可以事后设(因此 isDisposed
酒店形式),所以我假设它仍然可以留存或至少在部分?
我还知道,当一个对象超出范围,然后记为收集准备下一次通的垃圾收集器(尽管这可能需要的时间)。
因此,与这种考虑将其设置到 null
加快该系统解除记忆,因为它没有工作了,它不再是在范围和他们任何不良的副作用吗?
MSDN条款从来没有这样做的例子和目前我这样做因为我不能 看到损害。然而,我遇到一个混合的意见,因此任何评论意见是有用的。
解决方案
卡尔是绝对正确的,没有必要设置的对象null后使用。如果一个目实现了 IDisposable
, ,只要确定你的呼叫 IDisposable.Dispose()
当你完成,对象(包裹 try
..finally
, 或者, using()
块)。但即使如果你不记得打电话 Dispose()
, ,finaliser方法上的目的应该叫 Dispose()
对于你。
我认为这是一个很好的治疗:
和这个
没有任何一点在试图猜测的GC及其管理战略,因为这是自我调节和不透明的。有一个良好的讨论有关内部运作与杰弗里*里希特点的净石头在这里: 杰弗里*里希特窗户上的存储器模型 和 里克特夫妇的书 CLR通过C# 第20章具有极大的治疗:
其他提示
另一个原因,以避免设置的对象为空时你与他们做的是,实际上,它可以让他们活着更长的时间。
例如
void foo()
{
var someType = new SomeType();
someType.DoSomething();
// someType is now eligible for garbage collection
// ... rest of method not using 'someType' ...
}
将允许对象称,由someType要GC会后呼吁"或重写现有的"但是
void foo()
{
var someType = new SomeType();
someType.DoSomething();
// someType is NOT eligible for garbage collection yet
// because that variable is used at the end of the method
// ... rest of method not using 'someType' ...
someType = null;
}
有时可能保持对象活着,直到结束的方法。的 JIT通常将优化掉分配给null, ,所以两位数的代码是一样的。
没有不null的对象。你可以检查出来的 http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx 更多信息,但是设定事null不会做任何事情,除了肮脏你的代码。
也:
using(SomeObject object = new SomeObject())
{
// do stuff with the object
}
// the object will be disposed of
在一般情况下,没有必要空物体使用之后,但在某些情况下,我找到这是一个良好做法。
如果一个对象实现IDisposable和存储在一个领域,我认为这是很好的null它,只是为了避免使用设置的对象。错误的以下的排序可能是痛苦:
this.myField.Dispose();
// ... at some later time
this.myField.DoSomething();
这是很好的空领域后处置它,并且得到一个NullPtrEx权利在行领域被再次使用。否则,可能会遇到一些神秘的错误的路线(根据什么或重写现有的)。
有机会,你的代码不是结构紧密,如果你觉得需要 null
变量。
有一定数量的方式的范围限制的一个变量:
如前所述通过 史蒂夫也
using(SomeObject object = new SomeObject())
{
// do stuff with the object
}
// the object will be disposed of
同样,你可以简单地使用括号:
{
// Declare the variable and use it
SomeObject object = new SomeObject()
}
// The variable is no longer available
我发现,使用括号,没有任何"标题"为清洁的行为,并帮助使它更加可以理解的。
唯一的时候你应该设置一个变量空是当可变不出去的范围和不再需要的相关数据。否则就没有必要。
在一般没有必要设置为空。但是假设你有一个重功能。
然后你可能会这样做,因为你不想叫处理两次,由于一些处理可能不是正确实施和投掷系统。ObjectDisposed例外。
private void Reset()
{
if(_dataset != null)
{
_dataset.Dispose();
_dataset = null;
}
//..More such member variables like oracle connection etc. _oraConnection
}
这种"没有必要设置的对象为空之后使用"不是完全准确。有时候你需要空变量之后处理。
是的,你应该总是呼叫 .Dispose()
或 .Close()
在任何拥有它,当你完成。它文件处理、数据库连接的或一次性的对象。
分开是非常实用模式的延迟加载.
说我已经和实例 ObjA
的 class A
. Class A
有一个称为公共财产 PropB
的 class B
.
在内部, PropB
使用私人变的 _B
和defaults to null.时 PropB.Get()
使用它检查看看 _PropB
是空的和如果是,打开了所需资源的实例 B
入 _PropB
.然后,它返回 _PropB
.
以我的经验,这是一个非常有用的伎俩。
在这里需要null来是如果你重新设置或改变在某些方面的内容 _PropB
是孩子的前面值的 A
, 你会需要处理和空了 _PropB
所以延迟加载可以重新设置,以获取正确价值,如果代码要求。
如果你只做 _PropB.Dispose()
不久之后预计的空检查对延迟加载要取得成功,它不会是空的,你会看到陈旧的数据。在生效,必须null后 Dispose()
只是要确定。
我肯定希望它们否则,但是我已经得到了代码现在表现出这种行为以后一个 Dispose()
上 _PropB
和外面的叫功能,没有处置(并因此几乎的范围),私人支柱仍然没空,并且陈旧的数据是仍然存在。
最终,设置财产,将空出来的,但是这已经不确定性,从我的角度。
核心的原因,如dbkk暗示是,父容器(ObjA
与 PropB
)是保持的实例 _PropB
在范围,尽管所 Dispose()
.
在某些情况下是有意义的null引用。例如,当你在写一个收集--就像一个优先排队-和你的合同,你不应该让那些对象活着的客户之后的客户已经删除他们的队列。
但是,这种事只有事项中长期居住的藏品。如果队列不要生存端的功能,它的创建中,那么它事关整个少很多。
在一个整体,你真的不该打扰。让我们编译器和GC做他们的就业机会,所以你可以做你的。
看看这篇文章: http://www.codeproject.com/KB/cs/idisposable.aspx
大部分设置一个目空没有任何影响。只有时间你应该确保这样做是如果您使用的是一个"大象",这是一个大于84K在大小(如位图).
斯蒂芬*克利里介绍的非常好,在这个员额: 我应该设置的变量空,以协助收集垃圾?
说:
简短的回答,对于不耐烦的 是的,如果变量是一个静态的领域,或者如果你正在写一枚举的方法(利用率回)或异步方法(使用异步,并等待着).否则,没有。
这意味着在常规方法(非枚举并非是异步的),不设置地方的变量,方法参数,或实例领域为空。
(甚至如果你执行IDisposable.处理的,你仍然不应当设置变量null)。
重要的是,我们应该考虑的是 静态领域.
静态的领域总是根的对象, 所以他们都是 总是被视为"活着" 通过垃圾的收集器。如果一个静态的领域引用的对象不再需要,它应该被设置为空因此,垃圾收集器会把它作为有资格获得集合。
设定的静态领域为空是毫无意义,如果整个过程中被关闭。整个堆是关于将垃圾收集在这一点上,包括所有根源的对象。
结论:
静态领域;就是这样。什么是 浪费时间.
我相信通过设计的GC实现,你不能 加速 GC与无效.我敢肯定他们会愿意,你不用担心自己如何/何时GC运行--把它像这种无处不在 正在 保护和看着和为你...(弓头下,提出了拳头向天空的)...
就个人而言,我经常明确地设定的变量空当我这样做与他们作为一种形式的自文件。我不宣布、使用、然后设置为空之后--我null后立即他们不再需要。我是说,明确,"我很正式做你走了..."
被剥夺必要的GC会的语言?没有。它是有用的GC?也许是也许不知道,通过设计,我真的不能控制它,而无论今天的回答这个版本,或者说,未来的GC的实现方式可以更改的答复超出了我的控制。另外,如果时零优化了这是小小的更多花式 评论 如果你会。
我想如果它使我的意图清晰到下一个可怜的傻子是谁下我的脚步,如果它 "可能" 潜在的帮助GC有时候,那么它就值得我。主要是它让我觉得整洁和清除,以及蒙戈喜欢的感觉整理和明确的。:)
我看它像这样:编程语言的存在,让人们得到其他人的想法的意图和一个编译器工作的请求做什么--编译器转换,要求成不同的语言(有时几个)一CPU--CPU(s)可以得到什么叫声语言使用,你的标签设置、评价、风格的重点,变名称、等等。-一个CPU的所有有关的位流,告诉它什么登记册和操作码和存储地点到旋转.许多事情编写代码,不转换成什么样的消耗CPU在序列,我们指定。我们C、C++、C#、口齿不清,Babel、汇编或无论是理论上而不是现实中,书面声明的工作。你看到的不是你得到的是什么,是的,即使在汇编的语言。
我理解的心态"不必要的东西"(如空白行)"只不过是噪声和混乱的代码。" 这是我早些时候在我的职业;我完全得到这一点。在这个时刻,我倾向,这使得码更加清晰。它不喜欢我甚至增加50行的"噪声"我的计划--这是一个几条线这里或那里。
也有例外的任何规则。在方案的挥发性存储器,静态存储器,比赛的条件下,单身,使用"过时"的数据和所有类型的腐烂,这是不同的:你需要管理自己的记忆,锁定并消除为恰当的,因为存储器不是部分的GC会宇宙-我希望每个人都明白这一点。其余的时间与GC会的语言,这是一个问题的风格,而不是必要或保证提高性能。
在一天结束时确定你明白什么是合格的GC和什么不是;锁,处理和消除适当;蜡蜡;吸气,呼气;和其他的一切我说:如果感觉好,这样做。你的里程可能会有所不同...因为它应该...
一些对象的假设 .dispose()
方法其部队的资源,以从存储器。