什么时候必须在VB6中将变量设置为"Nothing"?

Mat*_*ard 10 vb6 memory-leaks

在我的一个VB6表单中,我创建了几个其他Form对象并将它们存储在成员变量中.

Private m_frm1 as MyForm
Private m_frm2 as MyForm

// Later...
Set m_frm1 = New MyForm
Set m_frm2 = New MyForm
Run Code Online (Sandbox Code Playgroud)

我注意到,只要创建并销毁此(父)表单,我就会泄漏内存.是否有必要对我来说,这些成员变量分配到NothingForm_Unload()

一般来说,什么时候需要?

已解决:当我Unload对相关表单执行操作时,此特定内存泄漏已得到修复,而不是在我将表单设置为时Nothing.我设法通过显式设置类模块的一些实例来删除一些其他内存泄漏Nothing.

Kon*_*lph 8

实际上,VB6 就像C++一样实现RAII,这意味着本地声明的引用会Nothing在块结束时自动设置.同样,它应该在执行后自动重置成员类变量Class_Terminate.但是,有几份报告说这是不可靠的.我不记得任何严格的测试,但最好的做法是手动重置成员变量.

  • 我怀疑那些关于它不可靠的谣言更可能是因为开发人员失去了他们的参考资料.我已经在VB6中编写了10年的编码,而且我唯一需要明确需要将对象设置为空的时候就是防止循环. (5认同)

小智 8

@Matt Dillard - 没有设置这些可以解决你的内存泄漏问题吗?

VB6没有正式的垃圾收集器,更像是@Konrad Rudolph所说的.

实际上,在我的表单上调用unload似乎是确保清理主表单以及每个子表单清理其操作的最佳方法.

我用一个空白项目和两个空白表格测试了这个.

Private Sub Form_Load()
  Dim frm As Form2
  Set frm = New Form2
  frm.Show
  Set frm = Nothing
End Sub
Run Code Online (Sandbox Code Playgroud)

运行后,两个表格都可见.把frm设置为什么都没有做得好......没什么.

在settign frm为空之后,打开此表单的唯一句柄是通过引用.

Unload Forms(1)
Run Code Online (Sandbox Code Playgroud)

我看到问题了吗?

  • 玩笑


Gui*_*ips 5

VB 中的对象具有引用计数。这意味着一个对象会记录有多少其他对象变量持有对它的引用。当没有对该对象的引用时,该对象将被垃圾回收(最终)。此过程是 COM 规范的一部分。

通常,当本地实例化的对象超出范围(即退出子)时,其引用计数减一,换句话说,引用该对象的变量被销毁。因此,在大多数情况下,您不需要在退出 Sub 时显式设置一个等于 Nothing 的对象。

在所有其他情况下,您必须将对象变量显式设置为 Nothing,以减少其引用计数(减一)。将对象变量设置为Nothing,不一定会破坏该对象,您必须将所有引用设置为Nothing。对于递归数据结构,这个问题会变得特别严重。

另一个问题是在对象变量声明中使用 New 关键字时。对象仅在第一次使用时创建,而不是在使用 New 关键字时创建。在声明中使用 New 关键字将在每次引用计数变为零时重新创建第一次使用的对象。因此,将对象设置为 Nothing 可能会破坏它,但如果再次引用该对象,则会自动重新创建该对象。理想情况下,您不应使用 New 关键字进行声明,而应使用没有这种复活行为的 New 运算符。