在VB6 / VBA中是否真的需要对象清除/数组释放(优点/缺点?)

时间:2009-10-06 13:58:35

标签: vba vb6 static-analysis

我从VB学到的很多东西都是从静态代码分析(特别是Aivosto的项目分析器)中学到的。它检查的一件事是你是否清除了所有对象和数组。我曾经盲目地这样做,因为PA这么说。但是现在我对VB释放资源的方式了解得更多,在我看来,这些事情应该自动发生。这是VB6之前的遗留功能,还是有理由将对象显式设置为空,并在阵列上使用Erase?

5 个答案:

答案 0 :(得分:14)

{p {3}}的作者Matt Curland比我们大多数人都更了解Visual Basic,他认为这是浪费精力。请考虑这个引用(p110)关于DAO,即主要以Access数据库引擎为目标的COM数据访问库:

  

另一个糟糕的拆解代码示例。   DAO必须具有Close方法   以正确的顺序呼叫,并且   对象必须在中释放   正确的顺序(Recordset   例如,在数据库之前)。这个   单个穷人对象模型行为有   导致VB泄漏的误解   内存,除非你明确设置所有   局部变量无所不在   一个功能的结束。这是一个   一个完全错误的概念   精心设计的对象模型。 VB可以   在结束时更快地清除变量   子线比你可以从代码,和   它会检查变量,即使你   明确发布您的推荐。   你所做的任何努力都是重复的。

答案 1 :(得分:4)

正如我所理解的那样,问题与VB6(及其前身)源于COM及其引用计数垃圾收集系统这一事实有关。

想象一下,例如,您从第三方库声明了对对象的引用。该对象具有COM引用计数,用于使其保持活动状态并确定何时应该销毁它。当你将它设置为Nothing时,它不会被破坏,但是当对象的引用计数达到零时。

现在,并非所有COM组件都是用Visual Basic编写的。有些是用C或C ++编写的。所有语言都不存在结构化异常处理。因此,如果发生错误,则无法保证对象上的引用计数被正确减少,并且已知COM对象的挂起时间比预期的要长。这本身就不是Visual Basic的问题。这是一个COM问题。 (而且,您可能会注意到,这就是.NET不使用引用计数的原因。)

这就是为什么Visual Basic开发人员在退出例程之前对释放对象引用的迷恋。你根本不知道你正在分配的组件是什么。但是当你发布它的引用时,你至少会释放你的引用计数。它几乎成了宗教的口头禅。声明,使用,发布。这是COM的做事方式。

当然,在解除引用我在堆栈上声明的变量时,Visual Basic可能会更好或更快。但该死的,我希望看到这些物品被释放是显而易见的。当你试图追踪内存泄漏时,一点点保证会很长。

答案 2 :(得分:2)

您是否已阅读此Aivosto web page(来自Project Analyzer的创建者)?

  

如果您使用静态变量,   回收记忆很重要   他们在你不需要的时候占用了   变量了。有动力   变量记忆不是那么多   问题,因为它们被摧毁了   当程序结束时。

换句话说,您不必担心清除普通的非静态局部变量。

答案 3 :(得分:0)

我总是为了良好的练习而做,你永远不知道如果你陷入其中并且你的对象没有被解除分配,异常可能会做什么。你应该在finally语句中重新使用它们并确保它们没有使用任何内存,否则你可能会遇到内存泄漏。

我在一个简单的时间跟踪器系统中遇到了一个问题,其中服务器一直随机崩溃,需要花费数周的时间来确定它是一个本身应该自行破坏的对象的内存泄漏。我的代码被抛入异常并且从未在自身导致服务器(实际网站而不是整个服务器)崩溃后清理。

答案 4 :(得分:-2)

是的,将所有对象设置为Nothing并尽可能多地清理。 VB6因没有清理你的东西而导致内存泄漏而臭名昭着。垃圾收集在VB6 / VBA中低于标准。