2

我最近看到一些 VB .NET 代码如下:

Dim service = ...
Try
   ...
   service.Close()
Finally
   service = Nothing
End Try

将 Nothing 分配给服务是否有任何作用?如果是垃圾收集问题,我假设当“服务”超出范围时,引用的对象将被垃圾收集,并且在对象上调用 dispose 方法。

在我看来,分配这个变量 Nothing 真的不能做任何事情,因为周围可能有另一个对该对象的引用,所以无论如何都要检查引用计数。

4

6 回答 6

4

它只释放引用,这可能意味着该对象可用于垃圾回收(仍然可能有其他变量引用同一对象)。如果对象实现了IDisposable,则需要Dispose显式调用,否则可能会发生资源泄漏。

于 2009-07-20T20:25:16.403 回答
3

您会看到旧的 VB6 代码,其中分配 Nothing 减少了 COM 对象的引用计数。

于 2009-07-20T20:24:46.153 回答
2

在大多数情况下,将 null (Nothing) 分配给引用对垃圾收集没有任何影响。

垃圾收集器不关心范围,它只关心使用情况。在代码中最后一次使用对象的点之后,垃圾收集器知道它可以收集它,因为它不会再被使用了。

将 null 分配给引用并不算使用对象,因此最后一个使用点是在该代码之前。这意味着当您清除引用时,垃圾收集器可能已经收集了对象。

(在调试模式下,虽然变量的使用扩展到了它的范围,因此调试器可以在整个范围内显示变量的值。)

于 2009-07-20T20:51:00.547 回答
1

正如大家已经说过的,设置为空不会强制垃圾收集,如果你想强制GC那么你会更好使用using ke这个词

   Using objA As A = New A()
       objA.DoSomething()
   End Using

您仍然不需要设置为空,因为 End Using 告诉垃圾收集不再使用该对象

于 2009-07-21T08:56:42.600 回答
1

将 NULL 分配给 .NET 中的引用无助于清除对象。它可能会帮助垃圾收集器在某些极端情况下运行得更快一点,但这根本不重要。它也不会调用 dispose(在处理一次性时)

无论如何,我喜欢分配 NULL 以明确声明我将不再使用该其他对象。所以它与捕捉错误有更多的关系(你会得到一个空引用异常,而不是可能调用一些其他对象——这可能会失败,甚至会默默地产生一些副作用。)

因此,在关闭另一个对象(文件或其他)后分配 NULL 是一种简化调试的“代码清洁度”,它对垃圾收集器没有帮助(除了在一些非常奇怪的极端情况下 - 但是当你需要关心时,你会无论如何,对垃圾收集器的了解比你想知道的还要多……)

于 2009-07-20T20:46:12.553 回答
0

在 .net(或 Java)中了解变量、字段或类类型的其他存储位置Foo不包含Foo. 它包含对 a 的引用Foo。同样, aList<Foo>不持有Foos;它包含对Foos 的引用。在许多情况下,程序员会知道一个变量来保存对某个特定Foo. 不幸的是,编译器没有通用的方法来知道一个存储位置是否包含对一个对象的唯一现存引用,或者它是否包含许多中的一个。

主要规则是,在实际上不再需要它们的那一刻和放弃对它们的所有引用之间的某个时间,应该告诉IDisposable实现的对象不再需要它们。IDisposable如果一个对象还没有被Disposed,并且代码即将覆盖对它的唯一现存引用(通过存储null,或者通过存储对其他东西的引用),则该对象应该Dispose调用它的方法。如果存在对该对象的其他引用,并且这些引用的持有者希望继续使用它,Dispose则不应调用它。由于编译器无法判断哪种情况适用,因此它不会调用Dispose,而是将其留给程序员(希望程序员更好地了解是否调用它)。

于 2012-12-13T16:59:10.640 回答