如何在Delphi应用程序中分析过多的内存消耗(PageFileUsage)?

时间:2012-03-15 13:44:11

标签: delphi memory-management delphi-xe out-of-memory

这是对此问题的跟进:What could explain the difference in memory usage reported by FastMM or GetProcessMemoryInfo?

我的Delphi XE应用程序使用了大量内存,有时会导致内存不足异常。我正在尝试理解为什么以及导致这种内存使用的原因,而FastMM报告内存使用率很低,当请求TProcessMemoryCounters.PageFileUsage时,我可以清楚地看到应用程序使用了大量内存。

我想了解导致此问题的原因,并希望了解如何处理它:

  • 有没有办法知道该内存中包含的内容及其分配位置?
  • 是否有一些工具可以在Delphi应用程序中按行/过程跟踪内存使用情况?
  • 有关如何处理此类问题的一般建议吗?

编辑1 :以下是FastMMUsageTracker的两个屏幕截图,表明内存已由系统分配。

  • 在流程开始之前:

Before process starts

  • 流程结束后:

After process ends

图例:浅红色是FastMM分配的,深灰色是系统分配的。

我想了解是什么导致系统使用那么多内存。可能是通过了解该内存中包含的内容或代码或过程导致该分配的内容。

编辑2 :出于多种原因,我宁愿不使用完整版的AQTime:

  • 我正在使用多个虚拟机进行开发,他们的许可系统是PITA(我已经是TestComplete的注册用户)
  • LITE版本没有提供足够的信息,我不会浪费钱而不确定FULL版本会给我有价值的信息

还有其他建议吗?

2 个答案:

答案 0 :(得分:4)

你需要一个分析器,但即便如此,在很多地方和案例中都是不够的。此外,在您的情况下,您需要全功能的AQTime,而不是Delphi XE和XE2附带的精简版。 (AQTIME非常昂贵,并且令人烦恼地被节点锁定,因此不要认为我对SmartBear软件不感兴趣。)

问题在于,人们经常将AQTime Allocation Profiler误认为是一种查找泄漏的方法。它还可以告诉您内存的去向,至少在工具的限制范围内。在运行并消耗大量内存时,我点击运行 - >获得结果。

这是我的一个应用程序是AQTime中的配置文件,其Allocation Profiler正好显示了哪个类分配了堆上有多少个实例以及这些实例使用了多少内存。由于您使用FastMM报告了低Delphi堆使用率,这告诉我AQTime大多数通过delphi类名分析的能力对您来说也是无用的。但是,通过使用AQTime的事件和触发器,您可能能够弄清楚应用程序的哪些区域会导致“内存使用费用”,当这些区域发生时,费用是多少。 AQTime的实时检测可能足以帮助您缩小原因范围,即使它可能找不到哪种函数调用会自动导致大量内存使用。

enter image description here enter image description here enter image description here 列名包括“对象名称”,其中包括以下内容:   *所有delphi类,以及它们的实例数和堆使用情况。   *通过Win32调用分配的虚拟内存块。

它可以检测堆上的Delphi和C / C ++库分配,并且可以看到某些Windows-API级别的内存分配。

请注意对象的实时计数,即使用的堆中的内存量。

我通常试图通过在一些昂贵的操作之前和之后测量堆内存使用来计算特定操作的内存成本,但是在从那个昂贵的操作中清理(释放)内存之前。我可以在AQTime中设置事件点,当某个特定方法被点击或者我打开一个标志时,我可以在值之前和之后测量,然后比较它们。

单独的FastMM甚至无法检测非delphi分配或来自未由FastMM管理的堆的分配。 AQTime不限于此。

答案 1 :(得分:4)

另一个问题可能是堆碎片。这意味着你有足够的内存空闲,但所有空闲块都很小。您可以使用FastMM的源版本直观地看到它,并按建议使用FastMMUsageTracker.pas here