我的程序永远不会释放内存。为什么?

时间:2010-12-16 18:10:53

标签: delphi

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

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

这不是泄密!
FastMM(设置为激进)表示关闭程序时没有内存泄漏。有关其不是泄漏的其他证据,请参阅我的答案帖子。

我发布内容
许多人告诉我,关闭一个儿童窗户只能隐藏它。我知道。我使用“Action:= caFree”来实际发布表单。每个表单都负责释放它所拥有的控件。

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


Delphi 7,Win 7 32位
类似帖子:
Can memory be cleaned up?
When to call SetProcessWorkingSetSize? (Convincing the memory manager to release the memory)

5 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:4)

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

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

<强>&LT;编辑&gt;
这是目录FastMMUsageTracker.pas中的...\FastMM\Demos\Usage Tracker 使用该单位,然后调用其中的ShowFastMMUsageTracker函数。 您可以偶尔刷新该表单,以查看内存消耗的增长情况。 我已经添加了FastMMUsageTrackerProject示例on-line,包括更新FastMM4,以便更轻松地检查和调试内存泄漏:

  • FastMMUsageTracker单元中的表单现在可以调整大小,其中的控件以正确的方式锚定
  • 有一个新的FastMmBootstrapUnit单元,可以更轻松地调试特定的内存泄漏

我上周拿到的东西是第三方DLL,它不是用Delphi编写的 DLL使用Windows GlobalAlloc调用发生内存泄漏,FastMM不会跟踪它。

注意:我即将在

上发布更新到FastMM

- 的Jeroen

答案 2 :(得分:4)

<强>答案:

我刚从项目中删除了FastMM,程序在释放所有子窗口后返回到几MB。许多人可能会争辩说,这不是一种不当行为,FastMM正在这样做,以便进行某种纠结的内存优化。他们可能是真的。但是,它可能对我的应用程序有利,但它可能不适合其他运行的应用程序。

所以,至少我们知道是谁造成的。我担心整整一天可能程序正在泄漏RAM就像一个旧桶。我现在感到宽慰。

更新:

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

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

答案 3 :(得分:0)

FastMM内存泄漏跟踪的主要限制是它只能在关闭程序时运行。可能是您仍然保留对关闭程序时清理的对象或其他数据的引用,但在此之前保持不变。

例如,当您关闭MDI子窗口时,您是否对它们调用Free或Release,或者只是让它们消失?如果他们被隐藏但没有被释放,他们仍然会留在记忆中。

答案 4 :(得分:0)

如果您关闭MDI表单,则不会自动释放它。使用Action = caFree(google for that)确保表单也被释放。