没有GDI泄漏的VB6内存泄漏

时间:2011-09-13 18:10:43

标签: memory-leaks vb6 memory-management

我在调试VB6代码中的内存泄漏时发现的所有建议都集中在GDI泄漏上。然而,在我的情况下,证据表明我没有GDI泄漏,但可能确实有内存泄漏。什么可能是导致这种泄漏的可能候选人,和/或帮助我确定导致此程序的部分程序的好工具?

3 个答案:

答案 0 :(得分:2)

不幸的是,VB6没有足够的调试工具来检测对象泄漏。我通常在每个类,表单或用户控件中使用几个辅助函数在我自己实现实例簿记。基本模式就像这样

Private Const MODULE_NAME As String = "<<class_name_here>>"

#If DebugMode Then
    Private m_sDebugID          As String
#End If

#If DebugMode Then
    Private Sub Class_Initialize()
        DebugInstanceInit MODULE_NAME, m_sDebugID, Me
    End Sub
#End If

#If DebugMode Then
    Private Sub Class_Terminate()
        DebugInstanceTerm MODULE_NAME, m_sDebugID
    End Sub
#End If

帮助程序函数DebugInstanceInit生成下一个顺序ID并将其分配给m_sDebugID,然后将模块名称和ObjPtr(Me)存储在集合中,并以id键入。

帮助程序函数DebugInstanceTerm使用m_sDebugID作为关键字从集合中删除条目。

这样,在应用程序执行的每个时刻,您都可以转储此实例集合,并识别已分配但仍未终止的对象的计数和类型。如果表单的连续打开和关闭会增加对象计数,则可能是由于循环引用(例如collection-&gt;条目和entry-&gt;集合)而泄漏对象。

大多数框架和其他语言都内置了这种簿记(至少在调试版本中),但遗憾的是VB6对源代码元数据(MODULE_NAME,FUNC_NAME,LINE_NUMBER)和对象生存期管理的支持很少。缺乏实现继承也在这里受到伤害。

答案 1 :(得分:1)

通常,您必须注意循环引用。在VB6中,只要在某处引用了对象,对象就会保留在内存中。因此,如果您有一个对象类型变量作为表单的成员(例如),那么它将在内存中,直到该表单被终止(除非您明确地将其设置为早于当然)。那个参考链可以非常深入:

这里,FormA将ObjectB和ObjectC保留在内存中:

FormA - &gt; ObjectB - &gt; ObjectC

你需要注意的是这样的事情:

FormA - &gt; ObjectB&lt; - &gt; ObjectC

ObjectB具有对ObjectC的引用,而ObjectC具有对ObjectB的后引用或父引用。即使FormA被终止或以其他方式清除它对ObjectB的引用,ObjectB和ObjectC将永远存在并代表内存泄漏。

答案 2 :(得分:1)

查找内存泄漏的好工具是删除程序。你可以尝试一下。并检查一件事 - 是否还有GDI泄漏。你必须确定!