循环和垃圾回收

4
我正在开发一个Web应用程序,遇到了以下情况。
Dim a as Object
Dim i as Integer = 0

Try

    For i=1 to 5

        a = new Object()

        'Do stuff '

        a = Nothing

    Next

Catch

Finally

   a = Nothing

End Try

在循环中,我需要执行a = Nothing吗?还是垃圾回收器会清理a的内存空间?

5个回答

12

在.NET中,通常你不需要将变量引用设置为Nothing(在C#中为null)。垃圾回收器最终会进行清理。当引用超出范围时(无论是当方法退出还是当该类的对象被完成时),引用本身将被销毁。请注意,这并不意味着对象已被销毁,只是对其的引用已被销毁。对象仍将由垃圾回收器非确定性地销毁。

然而,将引用设置为Nothing可以向.NET提供一个提示,表明该对象可能是垃圾,而且不会有任何损害-除了代码混乱的问题。如果您想保留它,请将其从Try块中删除;它已经在Finally块中,因此始终会被调用。(除了某些灾难性的异常;但在这些情况下,它也不会在Try块中被调用!)

最后,我必须承认我同意Greg的看法:如果没有这个操作,你的代码会更加简洁。告诉运行时引用已经完成很好,但绝对不是必要的。说实话,如果我在代码审查中看到这个,我可能会让开发人员这样重写:

Dim a as Object
Dim i as Integer = 0

For i=1 to 5
    a = new Object()
    'Do stuff
Next

5
将变量设置为null实际上可能会导致对象的生命周期延长而不是缩短(http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx)。尽管该文章的主旨是正确的——不必费心将事物设置为null。 - Greg Beech
触动人心。.NET JIT 以其智能和高效率的表现一直让我感到惊讶! - John Rudy

5
几乎从不需要显式地将Nothing分配给变量。垃圾收集器的工作是为您处理内存分配,特别是为了减轻您的这一责任。因此,在循环内部您不需要分配a = Nothing
您也不需要在整个代码块周围使用try/finally块来分配Nothing。这只是额外的杂物,运行时系统会自动处理。

2

不需要手动释放内存,.NET有自带的垃圾回收机制。而且由于这段代码是在方法作用域中,垃圾回收机制会清理掉任何本地变量。


0

垃圾回收器会清理它。


0

就像上面所有人所说的,您不需要显式地将变量设置为 null,因为它会自动处理。但是,如果出于某种原因您想强制 GC 进行垃圾回收,可以运行以下代码:

System.GC.Collect()

强制进行垃圾回收可能是一个非常糟糕的想法。(在Java中绝对是这样!) - Stephen C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接