【问题标题】:Knowing where memory is being allocated using FastMM知道使用 FastMM 分配内存的位置
【发布时间】:2013-01-01 16:36:11
【问题描述】:

我正在尝试使用 Delphi 7 调试大型应用程序中的内存使用情况。我能够安装 fastmm debug full dll 并解决一些泄漏问题。

我还安装了内存使用跟踪器,让我可以查看分配了哪些块以及它们的大小。

我的问题是,有没有办法找出块的分配位置?我知道这是可能的,因为如果没有释放内存,则会打印堆栈跟踪。有没有办法“戳”fastmm 让它打印给定分配的堆栈跟踪?

附带问题:如果知道分配的起始地址,有没有办法找出对象是哪个类? (假设分配是针对一个对象的。

【问题讨论】:

    标签: delphi fastmm


    【解决方案1】:

    如果您使用 FullDebugMode 并启用将数据写入文件的条件,那么您应该得到您所要求的。当程序关闭时,它将为每个泄漏的分配写出堆栈跟踪。 (如果您正在调试一个存在大量内存泄漏的程序,这可能需要一段时间。如果泄漏的项目是一个包含许多其他对象的容器,我认为它会使关闭持续 10 分钟或更长时间。)

    【讨论】:

    • 是的,我现在明白了,但是我遇到的问题是,当我关闭应用程序时,所有内存都被很好地清理了 - 我想知道给定时间点的信息 - 当一切都已加载到应用程序中。
    【解决方案2】:

    考虑到您在评论中说应用程序的内存在应用程序关闭时得到很好的清理,听起来您正在寻找 逻辑 内存泄漏 - 换句话说:存活时间超过需要,但是当完成应用程序的时间到来时,它们会被清理,因为存在清理它们的代码。

    例子:

    • 使用应用程序作为所有者创建一个 TForm,引用它的变量是 Delphi 在创建表单单元时创建的全局变量。
    • 将表单的 CloseAction 配置为 caHide(在 OnClose 事件中)
    • 显示表单,对其进行操作
    • 关闭表单,在应用关闭之前不再使用它
    • 关闭应用程序,这会使应用程序清除它拥有的所有对象

    所以您有 逻辑内存泄漏,但没有 物理内存泄漏 - 这是 FastMM 可以轻松检测到的类型。由于您不打算让我们假设的 TForm 在应用程序完成之前一直存在,因此它在语义上泄漏了,但由于它被引用并且在应用程序结束时有代码破坏它,FastMM 是正常的分配。

    也就是说,您似乎不需要内存管理器的内存转储,而是内存分析器。

    【讨论】:

    • 谢谢你的详细解答,delphi有没有内存分析器之类的东西?
    • @emuduguntar: AQTime 是我所知道的 Delphi 唯一的内存分析器,除了 FastMM 本身
    【解决方案3】:

    您可以:

    • 尝试使用LogAllocatedBlocksToFile 过程。如果其ALastAllocationGroupToLog 参数小于AFirstAllocationGroupToLog 或为零,则所有 块连同它们的分配调用堆栈一起被记录。但是,如果您的应用程序有很多内存分配,请准备好长时间等待。我经历了大约 4 小时的等待时间和 1.5Gb 的结果文件。 (旁注:使用glogg 来查看如此大的文件)
    • 修改FastMM4.pas,使实现的LogCallStack在界面中可见。或者您可以尝试直接从FastMM_FullDebugMode.dll 使用它

    关于附带问题:尝试使用DetectClassInstance 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 1970-01-01
      • 2016-06-16
      • 2019-12-27
      • 1970-01-01
      • 2013-11-27
      • 1970-01-01
      相关资源
      最近更新 更多