我最近看到一些VB .NET代码如下:
Dim service = ...
Try
...
service.Close()
Finally
service = Nothing
End Try
为服务分配什么都不做?如果它是垃圾收集问题,我假设当“服务”超出范围时,引用的对象将被垃圾收集并且对象调用dispose方法。
在我看来,分配这个变量Nothing不能真正做任何事情,因为可能有另一个对象周围的引用,所以无论如何都要检查引用计数。
答案 0 :(得分:4)
它只释放引用,这可能意味着该对象可用于垃圾收集(可能仍有其他变量引用同一对象)。如果对象实现IDisposable
,则需要显式调用Dispose
,否则可能会导致资源泄漏。
答案 1 :(得分:3)
否强>!
您正在看到旧的VB6代码,其中分配Nothing减少了COM对象上的引用计数。
答案 2 :(得分:2)
在大多数情况下,为引用分配null(Nothing)对垃圾收集没有任何影响。
垃圾收集器不关心范围,它只关心用法。在最后一次使用对象的代码中的点之后,垃圾收集器知道它可以收集它,因为它将不再被使用。
为引用分配null不算作使用对象,因此最后一个使用点在该代码之前。这意味着当您清除引用时,垃圾收集器可能已经收集了该对象。
(在调试模式下,虽然变量的使用扩展到了它的范围,因此调试器可以在整个范围内显示变量的值。)
答案 3 :(得分:1)
在.NET中为引用分配NULL无助于清除对象。它可能有助于垃圾收集器在某些角落情况下运行得更快,但这根本不重要。它也不会召唤处置(处理一次性用品时)
我喜欢分配NULL,无论如何明确声明我不会再使用那个其他对象了。所以它与捕获bug有很多关系(你会得到一个nullreference异常,而不是可能调用其他一些对象 - 这可能会失败甚至无声地产生一些副作用。)
所以在关闭另一个对象(文件或其他)后分配NULL是一个“代码清洁”的东西,可以简化调试,它对垃圾收集器没有帮助(除了一些非常奇怪的角落情况 - 但是当你需要关心的时候)你会比你想知道的更多地了解垃圾收集器......)
答案 4 :(得分:1)
正如大家已经说过的那样,设置为零并不强制垃圾收集,如果你想强制GC那么你会更好地使用使用ke字
Using objA As A = New A()
objA.DoSomething()
End Using
您仍然不需要设置为空,因为End Using告诉Garbage集合该对象不再被使用
答案 5 :(得分:0)
看起来答案在于对这篇文章的回复:Loops and Garbage Collection
答案 6 :(得分:0)
在.net(或Java)中理解类类型Foo
的变量,字段或其他存储位置不包含Foo
非常重要。它包含对Foo
的引用。同样,List<Foo>
不会保留Foo
个;它包含对Foo
的引用。在许多情况下,程序员将知道变量以保留对某些特定Foo
的唯一现存引用。遗憾的是,编译器没有一般的方法可以知道存储位置是否只保存对象的现有引用,或者它是否包含许多对象之一。
关于IDisposable
的主要规则是,应该告诉实现IDisposable
的对象在它们实际上不再需要它们之间的某个时间以及所有引用它们的时间之后不再需要它们被遗弃了。如果一个对象还没有Dispose
d,并且代码即将覆盖现有的唯一引用(通过存储null
,或者存储对其他内容的引用),该对象应该具有它的Dispose
方法被调用。如果存在对该对象的其他引用,并且这些引用的持有者希望继续使用它,则不应调用Dispose
。由于编译器无法判断哪种情况适用,因此它不会调用Dispose
,而是将其留给程序员(希望能更好地了解是否调用它)。