在Delphi App中监视内存使用情况

时间:2011-05-27 09:41:02

标签: delphi memory-leaks monitoring

我从一个离开公司的程序员那里继承了一个非常大的子系统,第一个业务是阻止进程耗尽内存。

基本上,它是一个循环通过数据集,在其中我们创建和销毁一个数据模块,该数据模块起飞并完成大量工作。只要创建了此数据模块,您就可以在任务管理器中看到内存使用一直在攀升,直到它爆炸为止。我似乎从几年前读过的一篇文章中回忆起,人们不应完全信任任务管理器报告的内容,因为这些值是估计而非实时。所以我正在寻找替代方案。

以下是我的尝试:

  1. ReportMemoryLeaksOnShutdown:=我的主项目文件中的True,但它什么也没有返回。因此要么它不监视在动态加载的包中泄漏的内存,要么在应用程序关闭之前释放内存。
  2. AQTime。这应该是一个非常的产品,但我发现它完全没有给人留下深刻印象。如果我使用分配探查器,我最终得到的数百行没有任何用处。只是一个内存地址,大小和“VCL标准分配”的内容。它应该按惯例分解信息,但我只是得到一个没有例行信息的平面列表。所以我认为它不起作用。
  3. 是否有其他工具可以帮助我跟踪分配和未释放内存的位置?我一直在评论各处的一些功能,以查看问题消失的地方,并检查显式分配的所有内容是否已被释放,但我仍然有泄漏,这可能是一个非常令人沮丧的过程。

5 个答案:

答案 0 :(得分:11)

FastMM包含一个简单的GUI,可在应用程序运行时显示内存使用情况。

示例项目位于Demos/Usage Tracker目录中。

答案 1 :(得分:3)

我绝对会使用AQTime和NOTHING ELSE来确定内存使用信息。以下是我希望您可以找到的内存使用信息的示例:

  1. 使用GetMem,TObject.Create。
  2. 分配内存的确切行
  3. 各种类类型使用的对象计数和总内存的漂亮计数器。
  4. 首先,让我们看看显而易见的事情:

    一个。您必须遵循AQTime的说明并设置项目设置,包括编译器和链接器设置,如帮助文件中所述。特别是您需要链接器选项中的Turbo Debugger(TD32)符号,以及为项目的任何其他调试版本设置的所有其他选项设置。

    B中。在使用自己的应用程序之前,您应首先尝试使用教程。

    简而言之,我已经大量使用了AQTime,当我遇到问题时,它们已经可以解决了,所以不要放弃AQTime。如果你无法让你的大应用程序工作,那么首先要学习如何测试小应用程序,演示或教程练习。

    更新:我刚刚自己测试了一下,我发现即使使用Allocation Profiler工作的AQTime 7的基本演示,我也遇到了问题。我正在使用AQTime 7.10.380专业版。

答案 2 :(得分:1)

要监视应用程序内存使用情况,您可以使用一些sysinternals工具(进程资源管理器,VMMap,Rammap)从操作系统的角度来看待它,但像AQTime这样的工具实际上会告诉您谁分配了内存,何时何地,只要您正确配置和使用它 - 它具有初始陡峭的学习曲线,仔细阅读文档,它不是“运行并读取结果”的工具。 爆炸应用程序可能不是任何泄漏,它可能只是加载并保留在内存中太多的数据。 很有可能你在内存中加载一个巨大的数据集,或类似的东西,例如双向数据集将缓存以前的记录以允许向后导航,一个单向的不会并且将使用更少的内存。在为varchar字段等设置内存时,有些库比其他库更有效(有些库可能总是分配varchar字段大小,其他库可能更智能,只是为给定的记录字段分配空间,尽管这样可以更好地管理记录更改难)。它可能是中间结果在内存中保存太久,数据结构选择错误或递归过多......很难说不看代码。

答案 3 :(得分:0)

在About.com上找到一些工具,用于Delphi内存泄漏:http://delphi.about.com/od/toppicks/tp/aatpmemleak.htm

答案 4 :(得分:0)

问题很可能是您在循环浏览数据集时将数据集保存在内存中,如果您有数十万(或数百万)条记录,则此数据可能会超过1 GB。我似乎记得一个数据集属性,UniDirectional,它确保可以随时释放内存,因为如果设置了此属性,则无法返回到数据集中的上一条记录(正常情况下)。

编辑:我认为这只适用于BDE,但默认情况下,如果我没有弄错的话,dbExpress会使用单向数据集。