是否有必要释放.Net中的内存,就像在VB6中一样?

时间:2009-10-20 14:40:46

标签: .net vb6 garbage-collection

我正在阅读有关VB6中Form的事件,例如“Unload”,“QueryUnload”和“Terminate”,以及“End”语句: https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5533338.html http://visualbasic.freetutes.com/learn-vb6-advanced/lesson6/p5.html

我曾经遇到过VB6应用程序的问题(它调用了许多windows'apis)。当我在主窗体的Unload事件中“结束”时,它崩溃了整个IDE!当我小心地关闭所有连接时,停止我的计时器,将所有形式设置为零,并且在完成所有清洁过程之后,将“结束”放在主窗体的终止事件的最后一行,一切正常。没有更多崩溃:)

我的问题是,是否有必要在.Net环境中完成所有这些“清理过程”。我知道垃圾收集器会清除所有可能导致问题的剩余位。

或者,无论是VB6还是.Net,在“结束”你的应用程序之前清理所有内容是一个好习惯吗?

7 个答案:

答案 0 :(得分:8)

不需要。

除非您引用COM或GDI +相关或非托管组件或您正在使用的资源,否则您必须使用Dispose方法手动处理引用。

请参阅此处more reference

答案 1 :(得分:3)

我认为最好的方法是:如果类实现IDisposable,那么你应该使用using语句。例如:

using(SomeDisposableClass instance = new SomeDisposableClass())
{
    // do stuff;
}

或者,在VB.NET中

Using instance As Stream = New SomeDisposableClass 
    '' Do stuff
End Using

当您的代码离开using阻止时,SomeDisposableClass将释放其资源。

答案 2 :(得分:2)

黄金法则:在.NET中,您不需要显式释放资源,除非它是非托管的,或者它使用非托管资源。

现在,诀窍在于确定资源是否使用非托管资源。如果组件实现了IDisposable接口,它将使用非托管资源,您需要通过调用其Dispose方法显式释放它。这里需要注意的是,一些对象是偷偷摸摸的,并且暴露出更直观的不同方法(比如DataReader的Close方法,它基本上处理了对象)。

但是,如果一个对象实现了IDisposable,那么应该在完成它后立即调用它的Dispose方法。如果对象是类级变量,那么您的类应该实现IDisposable,并且您对Dispose的实现应该处理对该对象的引用。

有关详细信息,请参阅MSDN上的Implementing Finalize and Dispose to Clean Up Unmanaged Resources

答案 3 :(得分:2)

无需在VB.Net 或VB6 中进行强迫清理。

我没有任何关于VB.Net垃圾收集的好答案,如果有问题的对象实现Using,请使用IDisposable

但我会这样说:它在VB6中非常相似。无需将表单或其他变量设置为Nothing或使用End。 VB6中的API调用相当于VB.Net中的非托管代码 - 两者都需要特别小心,特别是在释放资源时。我猜这是你的API调用导致崩溃。

另一个罪魁祸首可能是evil End statementEnd已被弃用in the VB6 manual,因为它会抑制Form_Unload等清理事件。您的整理代码(设置为Nothing)可能会导致您的终止事件(如Form_UnloadClass_Terminate)触发。也许事件处理程序然后正确清理了API调用?如果您刚刚避免使用End,则事件处理程序将被触发,并且可能没有必要将变量设置为Nothing。以下是VB6手册End topic的摘录:

  

注意 End语句会停止代码   突然执行。   您放入卸载的代码,   QueryUnload和Terminate事件   表单和类模块不是   执行......

     

End语句提供了一种方法   强迫你的程序停止。对于正常   终止Visual Basic程序,   你应该卸载所有表格。

答案 4 :(得分:1)

.NET应用程序擅长清理他们使用过的内存。但是,您仍需要确保关闭所使用的任何资源(例如文件,数据库连接等)。当程序退出时,它们将被清理,但是在代码中不再需要它们时,最好立即将它们清理干净。

答案 5 :(得分:1)

自动垃圾收集是一种祝福。

我记得我在VB5中创建的一个应用程序,我决定使用它提供的伪对象。我不记得为什么但是有一点不再需要先前创建的大量对象,所以起初我试图一次性释放它们。结果:应用程序冻结了几秒钟!我使用了一个列表中的脏对象,并使用计时器一次释放它们。

我承认我的设计可能不好,但无论如何在.NET中我都不会遇到同样的问题。

答案 6 :(得分:0)

.NET最大的问题是清除未受管理的资源。当您的应用程序退出其他应用程序时应该没问题。但就我个人而言,我建议您阅读一下MSDN文档中的.NET垃圾收集,以便您对它更加熟悉。