VB6程序内存泄漏诊断

生成 dump 文件

  1. 如果要分析 32bit 程序问题, 需要使用 32-bit dump文件, 比如 taskmgr.exe 32bit版, DebugDiag 工具. taskmgr.exe 32bit版路径是" " C:\Windows\SysWOW64\Taskmgr.exe
  2. 如果要分析 64bit 程序, 需要使用 64-bit dump文件, 有很多可用的dump文件生成工具, 比如 taskmgr.exe, DebugDiag 工具, winDbg, sysinternals 的process explorer 等.
    需要说明的是, 可以使用64-bit版本的DebugDiag程序来分析32-bit的dump文件,而不会遇到任何问题。

使用 DebugDiag 分析dump文件

当然可以使用微软的DebugDiag工具来分析user dump文件。该程序可以帮助诊断各种应用程序问题,如性能、内存泄漏和崩溃等. 功能较 winDbg 要弱不少, 优点是上手简单. 以下是使用DebugDiag分析user dump的详细步骤:

  1. 下载并安装DebugDiag工具
    访问微软官方下载页面(https://docs.microsoft.com/en-us/sysinternals/downloads/debugview)下载并安装DebugDiag工具。

  2. 启动DebugDiag
    安装完成后,打开DebugDiag。您将看到“DebugDiag 2 Collection”和“DebugDiag 2 Analysis”两个选项。我们需要使用“DebugDiag 2 Analysis”进行分析。

  3. 添加user dump文件
    单击“DebugDiag 2 Analysis”打开DebugDiag Analysis。在界面中,单击“Add Data Files”按钮,然后浏览并选择要分析的user dump文件。

  4. 选择分析类型
    添加user dump文件后,单击“Start Analysis”按钮。然后选择适用于您的问题场景的分析规则。例如,如果您要诊断内存泄漏问题,请选择“Memory Analysis”。单击“Next”继续。

  5. 开始分析
    确认分析规则后,单击“Start Analysis”按钮。DebugDiag将开始对user dump文件进行分析。分析完成后,它会生成一个MHTML报告文件,其中包含有关问题的详细信息和可能的解决方案。

  6. 查看报告
    打开生成的MHTML报告文件,查看分析结果。报告中可能包含有关异常、内存使用情况、调用堆栈等的详细信息。根据报告中的建议,您可以找到问题的原因并采取相应的解决措施。

使用 winDbg 分析dump文件

下载Debugging Tools for Windows,安装WinDbg或KD等调试工具, 具体步骤如下:

  1. 打开WinDbg或KD,选择打开Dump文件,打开你的user dump文件。
  2. 输入!analyze -v命令,分析dump文件,检查是否有内存泄漏报告。泄漏报告中会指出泄漏对象的类型和数量,这可以作为分析的提示。
  3. 输入!heap -stat命令,检查堆使用概况,看是否有异常的堆块数量。正常情况下应只有少量堆块,如果堆块数量过多,可能存在内存泄漏。
  4. 输入!handle命令,列出当前所有句柄,按类型分类。可以查找句柄中是否存在大量未释放的GDI/USER对象,这也可能导致内存泄漏。
  5. 输入!tok临时对象地址,查看对象 details。这个可以查看对象的类型,大小,引用计数等信息。通过这个了解对象的详细信息,分析是否存在异常。
  6. 使用!gcroot命令,可以跟踪对象的GC Root,查看哪些对象开启了引用链导致该对象无法被回收。这可以用来分析循环引用等情况。
  7. 利用WinDbg的GUI窗口,可以在“窗口”菜单中选择“显示全局符号”和“显示内存”等窗口,像寻找对象关系,更直观的查看和分析内存泄漏情况。
    如果需要,还可以加载SOS调试扩展插件,它有更丰富的CLR内存分析命令,可以分析managed代码的内存泄漏。
    所以,熟练使用WinDbg各种内存调试命令和窗口,是分析User Dump内存泄漏的关键。对内存和对象的熟悉,可以帮助更好的分析ROOT CAUSE,找到内存泄漏产生的原因。

VB6程序的内存泄漏分析方法

分析VB6程序的内存泄漏,可以从以下几个方面入手:

  1. 检查是否有循环引用。VB6使用引用计数内存管理,如果两个对象相互引用,但没有其他引用,就会产生循环引用导致内存泄漏。可以使用工具分析内存快照,查找环形引用链。
  2. 检查是否有未释放的COM对象。VB6使用COM对象,如果创建COM对象后没有调用Release方法释放,会产生内存泄漏。可以在内存快照中查找类名中包含“VB6”的对象,确认是否有未调用Release的对象。
  3. 检查Dynamic Arrays的使用。VB6的Dynamic Arrays如果redim后没有调用Erase清空,旧的数组空间不会释放,会产生内存泄漏。在代码中搜索redim确认后是否有及时调用Erase。
  4. 检查是否有事件无法解除订阅。如果有对象注册事件后被释放,但事件无法解除订阅,会产生内存泄漏。要确认对象释放前是否正确解除订阅所有事件。
  5. 使用vbWatch工具监视对象引用计数。这个工具可以实时显示对象的引用计数,可以观察对象从创建到释放的全过程,确认是否有引用计数无法下降到0的情况,从而找到内存泄漏的原因。
  6. rational Purify 这类内存泄漏检测工具也可以用于分析VB6程序的内存泄漏,它们可以自动检测上述几种情况,帮助程序员定位内存泄漏代码。

所以综上,要想分析VB6内存泄漏,关键是要熟悉VB6的内存管理机制,着重检查循环引用,COM对象释放,动态数组使用,事件订阅等情况。然后可以借助一些工具,观察对象生命周期,辅助查找内存泄漏代码。

使用vbWatch检查对象引用计数和内存泄漏

vbWatch是一款用于监视和调试Visual Basic 6.0应用程序的工具,它可用于检查对象引用计数和内存泄漏等问题。 网站

该工具提供了一个可视化的界面,可以显示应用程序中各种对象的引用计数,包括窗体、控件、类和模块等。它还可以监视对象的创建和销毁,以及在调试过程中查看变量和表达式的值。

除了对象引用计数的监视,vbWatch还包括许多其他特性,比如:

  1. 脚本编辑器:可以在应用程序运行时运行脚本,以便更方便地调试和测试应用程序。
  2. 日志记录:可将应用程序的运行日志保存到文件中,以便在出现问题时进行分析。
  3. 自动化:可以通过COM接口自动化vbWatch,以便更好地集成到自己的开发工作流程中。
    vbWatch是一个商业产品,需要购买许可证才能使用。它的价格因版本和许可证类型而异。不过,该工具提供了一个免费的试用版,可以在30天内免费试用,以便用户可以测试其功能和性能。

使用vbWatch的步骤如下:
在Visual Basic项目中添加一个引用,引入vbWatch.dll。这是一个COM组件。
在代码中实例化vbWatch对象:

Dim vw As New vbWatch.vbWatch

对任意对象调用vw.Watch()方法开始监视其引用计数:

vw.Watch(someObject)

此后,vbWatch will在后台跟踪这个对象的引用计数变化。
随时可以调用vw.Status()方法获取所有被监视对象的当前状态:

Dim status As String = vw.Status()

status会返回所有被监视对象的引用计数信息,如:

Object1: Ref Count=2 (Started at 3)
Object2: Ref Count=1 (Started at 1) 

当不再需要监视某对象时,调用vw.Unwatch(someObject)方法停止监视。

当不再需要vbWatch时,设置 vw = Nothing 结束其实例。

posted @ 2023-06-04 16:43  harrychinese  阅读(85)  评论(0编辑  收藏  举报