在Delphi应用程序中监视内存使用

在Delphi应用程序中监视内存使用,delphi,memory-leaks,monitoring,Delphi,Memory Leaks,Monitoring,我从一个离开公司的程序员那里继承了一个非常大的子系统,首要任务是阻止进程内存不足 基本上,它是一个通过数据集的循环,我们在其中创建和销毁一个数据模块,该模块将启动并执行大量工作。只要创建了这个数据模块,您就可以在任务管理器中看到内存使用一直在上升,直到它崩溃。我似乎还记得几年前读过一篇文章,文章中提到,人们不应该完全相信任务管理器报告的内容,因为这些值是估计值,而不是实时值。所以我在寻找替代品 以下是我尝试过的: ReportMemoryLeaksOnShutdown:=在我的主项目文件中为Tr

我从一个离开公司的程序员那里继承了一个非常大的子系统,首要任务是阻止进程内存不足

基本上,它是一个通过数据集的循环,我们在其中创建和销毁一个数据模块,该模块将启动并执行大量工作。只要创建了这个数据模块,您就可以在任务管理器中看到内存使用一直在上升,直到它崩溃。我似乎还记得几年前读过一篇文章,文章中提到,人们不应该完全相信任务管理器报告的内容,因为这些值是估计值,而不是实时值。所以我在寻找替代品

以下是我尝试过的:

  • ReportMemoryLeaksOnShutdown:=在我的主项目文件中为True,但它不返回任何内容。因此,它要么不监视动态加载的包中泄漏的内存,要么在应用程序关闭之前释放内存
  • 阿奎斯特时间。这应该是一款非常哇的产品,但我觉得它完全没有吸引力。如果我使用分配分析器,我最终会得到数百行没有任何有用的内容。只是一个内存地址、大小和类似于“VCL标准分配”的东西。它应该按例程分解信息,但我只得到一个没有任何例程信息的平面列表。所以我认为它不起作用

  • 有没有其他工具可以帮助我跟踪内存分配和未释放的位置?我已经在各处对一些功能进行了注释,以查看问题在哪里消失,并检查所有显式分配的功能是否都得到释放,但是我仍然有一个漏洞,这可能是一个相当令人沮丧的过程。

    在About.com上找到了一些用于Delphi mem漏洞的工具:

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


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

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

    问题很可能是在循环数据集时,您将数据集保存在内存中,如果您有数十万(或数百万)条记录,这可能会超过1 GB。我似乎想起了一个dataset属性,单向,它确保了内存可以在运行时释放,因为如果设置了此属性,则无法返回到dataset中的上一条记录(与正常记录一样)


    编辑:我认为这只是针对BDE,但如果我没有弄错的话,dbExpress默认使用单向数据集。

    我绝对会使用AQTime,而不是其他任何东西来确定内存使用信息。下面是一个我希望您能够找到的内存使用信息示例:

  • 使用GetMem、TObject.Create分配内存的确切行
  • 各种类类型使用的对象计数和总内存的漂亮计数器
  • 首先,让我们先把显而易见的事情弄清楚:

    答:您必须按照AQTime的说明设置项目设置,包括编译器和链接器设置,并在帮助文件中记录。尤其是在链接器选项中需要Turbo Debugger(TD32)符号,以及所有其他选项设置,就像为项目的任何其他调试版本设置一样

    你应该先尝试一个教程,然后再将其用于你自己的应用程序

    简言之,我一直在大量使用AQTime,当我遇到问题时,它们是可以解决的,所以不要在AQTime上放弃。如果你无法让你的大应用程序正常运行,那么从学习如何测试小应用程序、演示或教程练习开始


    更新:我刚刚自己测试了一下,我发现我甚至在使用分配档案器制作AQTime 7的基本演示时都遇到了问题。我使用的是AQTime 7.10.380 pro。

    数据集的负载有多重?您确定数据量不是太大吗?ReportMemoryLeaksOnShutdown on报告关闭时未释放的内存泄漏。运行时报告泄漏更加困难。如果您自己创建memleak,ReportMemoryLeaksOnShutdown会显示一些数据吗?就像在you.dpr?AQTime中的“TComponent.Create”一样,对我来说绝对是魔兽世界的产物。我想你应该花更多的时间来理解它,因为在我漫长的寻找一个更合适的内存泄漏调试器的过程中,调试器是徒劳的。@Cobus,你确定你正在耗尽内存而不是耗尽资源(窗口/字体/位图句柄)?“只要你正确地配置和使用它”-这是关键。如果你学会了如何使用它,它会给你想要的。+1你可以在你自己的项目中加入usage tracker表单,我将向你展示一个不断更新的内存的实时图形表示。相当整洁。我通常在
    {$IFDEF DEBUG}..{$ENDIF}
    之间包含它,以便