寻找记忆泡泡
Posted
技术标签:
【中文标题】寻找记忆泡泡【英文标题】:Finding a Memory Bubble 【发布时间】:2009-02-04 01:37:36 【问题描述】:这要么简单得可笑,要么太复杂。 . . .
在我们的应用程序中,有一个表单可以从数据库中加载一些数据并将其显示在网格中(简单地说)。刷新数据时,总内存使用量增加了大约 50K(毫无疑问取决于显示的数据量)。听起来像是内存泄漏,但是当我们关闭应用程序时,FastMM 设置为 ReportMemoryLeakOnShutDown := True,并且它不会报告任何异常的内存泄漏。
看来我们有一个记忆泡泡或记忆袋。每次运行时都会积累更多内存的东西。就像一个 TList 不断向其中添加新项目,但旧的永远不会被删除。然后在关闭过程中,所有项目都被销毁。网格中显示的行数并没有增加,但在幕后有很多对象列表使这项工作发挥作用,所以它可以在任何地方。
所以我的问题是,是否有人知道找出应用程序的哪些部分正在使用多少内存的好技巧。 . . .我可以想出很多乏味的方法(我正在这样做 - 检查我能找到的每个列表),所以我希望有人有我没有想到的技巧或技术。
提前致谢!
更新:每次刷新都会额外使用 10-50K 的内存。用户报告说应用程序最终会停止响应。它确实像内存泄漏,但 FastMM(内存管理器)没有看到任何泄漏。我会尝试一些其他的记忆工具。 . .
【问题讨论】:
“停止响应”部分使它听起来好像是一个 TList 或 TObjectList ,其 OwnObjects = True 不断增长,并且使用了 IndexOf 或类似的东西。你可能错过了一个清单。清除某处..... 【参考方案1】:只需按 F8 键通过关键部分并查看进程使用图(Mark Russinovich 的 Process Explorer 非常适用)。当你找到罪魁祸首的方法时,重复这个过程,但要进入那个方法。
【讨论】:
【参考方案2】:AQTime 等工具可以报告快照之间内存/对象使用情况的差异。这可能会帮助您找出持续增长的因素。
【讨论】:
【参考方案3】:看起来有一些内存是通过自定义 AllocMem() 调用分配的,绕过了 FastMM。
这可能是点赞。 Andreas has a solution for this
或其他一些分配某些东西的 InitXXX WinAPI 调用,而不释放。或者项目使用的其他一些第三方或windows dll。
【讨论】:
这可能是真的,但也可能不是。 FastMM 只能检测关闭时未释放的“泄漏”。在关机之前它永远不会检测到“泄漏”的东西。 克雷格,我在这里遗漏了一些东西。 FastMM 将检测通过 delphi mm 调用进行的任何分配和释放。您所说的“直到关闭为止泄漏的东西”是什么意思?例子? 我想我的意思是在你关闭应用程序之前你不会知道这是泄漏。 dmajkic,考虑 FDM= TMyDM.Create(Application);。所有者应该是包含类,而不是应用程序。所以这是一个泄漏,适用于所有运行时。但是 FastMM 不会报告它,因为它会在应用程序关闭时被释放。 然后吉姆可以对用户说这是一个功能:“我们正在兑现一些数据;我们不知道具体是什么,但它最终会发布”:-) 我的意思是“泡沫” " 没有在任何地方引用。是的,可以两者兼而有之。【参考方案4】:每次刷新数据时都会发生这种情况还是仅第一次发生这种情况?如果这只是第一次,则系统可能只是为您的应用程序保留内存,尽管此时它没有被使用。 (也许在某些时候新旧数据同时存在于内存中?)
有很多工具可以为您提供有关内存泄漏的信息,您是否尝试过其他工具?
【讨论】:
【参考方案5】:我不是 FastMM 专家,但我想在内存管理器获得内存后,在您释放对象/组件后,它会保留一些零或标志以备将来使用,我不知道,避免需要询问操作系统随时获取更多内存,例如缓存。
如何创建相同的表单/打开相同的数据,连续 N 次? 每次会增加50K吗?
【讨论】:
【参考方案6】:一旦我遇到了同样的问题。该应用程序肯定在泄漏,但我没有收到有关关机的报告。这样做的原因是我在项目的使用部分中包含了 sharemem。
您是否尝试过完整的 FastMM 版本?我发现调整它的设置可以让我获得更详细的内存使用信息。
【讨论】:
【参考方案7】:正如 Lars Truijens 所提到的,AQTime 提供了实时内存消耗图,因此在运行时,您可以在刷新数据时查看哪些对象正在使用更多内存。
【讨论】:
以上是关于寻找记忆泡泡的主要内容,如果未能解决你的问题,请参考以下文章