Delphi 我的程序从不释放内存。为什么?

Delphi 我的程序从不释放内存。为什么?,delphi,Delphi,我有一个MDI程序。启动时需要2-3MB内存。然后,在这个程序中,我创建了大约260个MDI子窗口(每个都有一个TStringGrid、一个位图和一些其他控件)并显示一些数据。该应用程序需要大约500MB才能加载所有这些窗口。如果我手动关闭每个MDI子级,应用程序仍然使用160MB的RAM。为什么它不返回到几MB的RAM?我应该担心这个吗?160MB对于只有1GB或RAM的系统来说太多了 注意:我使用任务管理器中的“工作集”列查看RAM统计信息。也许我需要一个更好的工具来读取RAM利用率。(私有

我有一个MDI程序。启动时需要2-3MB内存。然后,在这个程序中,我创建了大约260个MDI子窗口(每个都有一个TStringGrid、一个位图和一些其他控件)并显示一些数据。该应用程序需要大约500MB才能加载所有这些窗口。如果我手动关闭每个MDI子级,应用程序仍然使用160MB的RAM。为什么它不返回到几MB的RAM?我应该担心这个吗?160MB对于只有1GB或RAM的系统来说太多了

注意:我使用任务管理器中的“工作集”列查看RAM统计信息。也许我需要一个更好的工具来读取RAM利用率。(私有工作集仅比工作集小一点)

这不是泄漏
当我关闭程序时,FastMM(设置为积极)指示没有内存泄漏。请参阅我的回复帖子,以获取更多证据,证明这不是泄漏

我发布内容
很多人告诉我,关闭子窗口只会隐藏它。我知道。我使用“Action:=caFree”来实际发布表单。每个表单负责释放其持有的控件

回答
我发现FastMM对此负有责任。请参阅我在下面发布的答案


Delphi 7,Win 7 32位
类似帖子:


任务管理器不是检测内存泄漏的正确工具。Delphi分配大块内存,并保留它们以备将来使用,因此即使在释放所有资源后,分配的内存也会有所增加。任何其他结果(以及更详细的答案)只能通过使用专门的内存分析工具获得。AQTime是第一个出现在脑海中的,或者如果你能找到旧但有用的MemProof,它会对你有很大帮助(MemProof是免费的,对于内存分析来说,它比AQTime更方便)

FastMM内存泄漏跟踪的主要限制是,它只能在您关闭程序时运行。这可能是因为您仍然保留对对象或其他数据的引用,这些对象或数据在您关闭程序时会被清除,但会一直保留到那时


例如,当您关闭MDI子窗口时,是调用它们的Free或Release,还是只是让它们消失?如果它们被隐藏但未被释放,它们仍将在内存中。

很可能FastMM在应用程序终止时不会显示内存泄漏(例如,因为所有对象都是拥有的T组件,所有者会释放它们)。
但与此同时,在运行这些组件时,它们仍然可以存在,而且不能很快释放

您是否使用了显示当前内存使用情况的表单的FastMM单元


这是目录
..\FastMM\Demos\Usage Tracker
中的
FastMMUsageTracker.pas
使用该单元,然后调用其中的
ShowFastMMUsageTracker
函数。 您可以每隔一段时间刷新该表单,以查看内存消耗的增长情况。 我提供了一个
FastMMUsageTrackerProject
示例,其中包括一个更新的FastMM4,可以更轻松地检查和调试内存泄漏:

  • FastMMUsageTracker
    单元中的表单现在可以调整大小,其中的控件以正确的方式锚定
  • 有一个新的
    FastMmBootstrapUnit
    单元,可以更轻松地调试特定的内存泄漏
上周我手头有一个第三方DLL,它不是用Delphi编写的。
DLL使用Windows GlobalAlloc调用发生内存泄漏,FastMM未跟踪该调用

注意:我将在网站上发布一个对FastMM的更新


--jeroen

如果关闭MDI表单,它不会自动释放。使用Action=caFree(谷歌)确保表单也被释放。

回答:

我刚刚从我的项目中删除了FastMM,在释放了所有子窗口后,程序返回了几MB。许多人可能会争辩说,这不是一种错误行为,FastMM这样做是为了进行某种古怪的内存优化。他们可能是真的。但是,它可能对我的应用程序有好处,但对其他正在运行的应用程序可能没有好处

所以,至少我们知道是谁造成的。我整整一天都在担心梅的程序像个旧桶一样漏掉内存。我现在松了一口气

更新:

为了确认这个行为是由FastMM生成的(正如Barry Kelly所建议的),我创建了第二个程序,分配了大量RAM。Windows的RAM一用完,我的程序内存利用率就恢复到原来的值。
(注意:我并不是说FastMM中有bug!)


我的程序没有泄漏。问题已解决。

目前无法回答此问题。您如何知道您的应用程序仍在使用160MB或RAM???嗨,Andreas。如果您需要更多数据,请告诉我。a)工作集堆分配的可能重复b)任务管理器显示瞬时值,而不是统计>因此,即使在释放所有资源之后,分配的内存也会有一定的增加-----我知道这一点。但我没想到会有这么多。我要试试MemProof。编辑:实际上,如果它为最近关闭的每个窗口保留大约1MB的RAM,那么它是有意义的。如果你最小化你的程序,你的应用程序的内存使用会突然下降吗?那么你的结论是基于错误的统计数据。@Lars-我对这种行为很熟悉(似乎从WinXP开始就存在)。这是尝试的第一件事:)不幸的是,这个应用程序没有出现这种情况。我释放了表单。如果仅隐藏子窗体,则RAM量将不会从500 MB降至160MB。是否确定窗体仅用于包含对其显示的数据的引用的对象?可能不是表单无法释放内存。对另外,如果我无法释放某些对象(泄漏内存),FastMM会立即向我发起攻击