我找到的所有关于调试VB6代码中内存泄漏的建议都集中在GDI泄漏上。然而,在我的情况下,有证据表明我没有GDI泄漏,但可能确实有内存泄漏。什么可能是导致这种泄漏的候选原因,和/或好的工具来帮助我确定导致这种泄漏的程序部分?
发布于 2011-09-14 16:39:33
不幸的是,VB6没有足够的调试工具来检测对象泄漏。我通常使用几个helper函数在每个类、窗体或用户控件中自己实现实例记账。基本模式如下所示
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作为键从集合中删除条目。
这样,在应用程序执行的每时每刻,您都可以转储此实例集合,并识别已分配但仍未终止的对象的数量和类型。如果表单的连续打开和关闭增加了对象数量,则可能是由于循环引用(例如集合->条目和条目->集合)而导致对象泄漏。
大多数框架和其他语言都内置了这种记账功能(至少在调试版本中是这样),但不幸的是,VB6对源代码元数据(MODULE_NAME、FUNC_NAME、LINE_NUMBER)和对象生存期管理的支持很差。缺少实现继承也会影响到这一点。
发布于 2011-09-14 20:07:12
一般而言,您必须注意循环引用。在VB6中,只要某个对象在某个地方被引用,它就会一直留在内存中。因此,如果你有一个对象类型的变量作为表单的成员(例如),那么它将一直在内存中,直到该表单被终止(当然,除非你明确地将其设置为nother )。而这个参考链可能非常深:
在这里,FormA将ObjectB和ObjectC保存在内存中:
FormA -> ObjectB -> ObjectC
你需要注意的是这样的东西:
FormA -> ObjectB <-> ObjectC
ObjectB引用了ObjectC,ObjectC引用了ObjectB。即使FormA被终止或以其他方式清除它对ObjectB的引用,ObjectB和ObjectC也将永远存在,并表示内存泄漏。
发布于 2011-11-18 16:49:49
查找内存泄漏的好工具是deleaker。你可以试试。再检查一件事-- GDI是否还有漏洞。你一定要确定!
https://stackoverflow.com/questions/7406462
复制相似问题