问题标签 [fastmm]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
6 回答
5561 浏览

delphi - 如何使用 fastMM 追踪棘手的内存泄漏?

将项目从 Delphi 2007 升级到 Delphi 2009 后,我遇到了未知的内存泄漏,到目前为止,我一直在尝试使用 fastMM 对其进行跟踪,以下是 fastMM 堆栈跟踪报告的内容:

有时我会得到这个:

有没有更好的方法来找出真正导致内存泄漏的原因?

0 投票
2 回答
3055 浏览

delphi - FreeMM 与 ShareMem

我们有很多用 delphi 和 c++ builder 编写的 dll 库,并使用 sharemem 和 borlndmm.dll。

3thparty 库中的对齐问题迫使我们转向 delphi 2007 中的新内存管理器。

有人可以为我解释一下“共享内存管理器”吗?
SimpleShareMem 是 ShareMem 的替代品吗?
那么我们可以停止部署borlndmm.dll 吗?
我们是否也必须对 c++ 库做一些事情?
一些库可以使用 ShareMem 和一些 SimpleShareMem 吗?

谢谢,-素食主义者

0 投票
8 回答
5340 浏览

delphi - 为什么 Delphi 中的字符串内存过多?

我正在阅读一个包含 140 万行、大小为 24 MB(平均每行 17 个字符)的大型文本文件。

我使用的是 Delphi 2009,文件是 ANSI,但在读取时会转换为 Unicode,因此您可以说转换后的文本大小为 48 MB。

(编辑:我发现了一个更简单的例子......)

我将此文本加载到一个简单的 StringList 中:

我发现这些数据行似乎比它们的 48 MB 占用更多的内存。

事实上,它们使用 155 MB 内存。

我不介意 Delphi 使用 48 MB 甚至高达 60 MB 的内存管理开销。但是 155 MB 似乎过多。

这不是 StringList 的错。我之前尝试将这些行加载到记录结构中,并且得到了相同的结果(160 MB)。

我没有看到或理解是什么导致 Delphi 或 FastMM 内存管理器使用 3 倍于存储字符串所需的内存量。堆分配不可能那么低效,不是吗?

我已经对此进行了调试并尽可能地对其进行了研究。任何关于为什么会发生这种情况的想法,或者可能帮助我减少过度使用的想法将不胜感激。

注意:我以这个“较小”的文件为例。我真的想加载一个 320 MB 的文件,但 Delphi 要求超过 2 GB 的 RAM 并且由于这个多余的字符串要求而耗尽内存。

附录:Marco Cantu 刚刚发表了一份关于 Delphi 和 Unicode 的白皮书。Delphi 2009 将每个字符串的开销从 8 个字节增加到 12 个字节(对于指向字符串的实际指针,可能还要增加 4 个字节)。每 17x2 = 34 字节的行额外增加 16 字节几乎增加了 50%。但我看到超过 200% 的开销。额外的 150% 可能是什么?


成功!!感谢大家的建议。你们都让我思考。但我必须感谢 Jan Goyvaerts 的回答,因为他问:

...你为什么要使用 TStringList?文件真的必须作为单独的行存储在内存中吗?

这使我找到了一个解决方案,即我可以将我的行分组到我的程序知道的自然组中,而不是将 24 MB 文件作为 140 万行 StringList 加载。因此,这导致将 127,000 行加载到字符串列表中。

现在每行平均 190 个字符而不是 17 个。每个 StringList 行的开销是相同的,但现在行数要少得多。

当我将此应用到 320 MB 文件时,它不再耗尽内存,现在加载不到 1 GB 的 RAM。(而且加载只需要大约 10 秒,相当不错!)

解析分组的行会有一点额外的处理,但在每个组的实时处理中应该不明显。

(如果您想知道,这是一个家谱程序,这可能是我需要让它在不到 30 秒的时间内将大约 100 万人的所有数据加载到 32 位地址空间中的最后一步。所以我我们仍然有 20 秒的缓冲时间来将索引添加到数据中,这将需要允许显示和编辑数据。)

0 投票
6 回答
36549 浏览

delphi - 如何获取 Delphi 程序使用的内存

我知道如何使用 GlobalMemoryStatusEx 获取系统内存使用情况,但这告诉我整个操作系统正在使用什么。

我真的希望我的程序报告它单独分配和使用了多少内存。

我的 Delphi 2009 程序中是否有任何方法可以调用 Windows 函数或某些 FastMM 函数来找出仅由我的程序分配的内存?


重新审视我的问题,我现在已将我接受的答案更改为 @apenwarr 的 GetMemoryManagerState 答案。它产生的结果与我过去使用的 GetHeapStatus 函数(现已弃用)相同,而 GetProcessMemoryInfo.WorkingSetSize 给出了非常不同的结果。

0 投票
1 回答
2046 浏览

delphi - 如何在 DUnit 中使用 FastMM 启用内存泄漏跟踪?

在 GUI 测试运行器中,用于内存泄漏检查的菜单项处于非活动状态(灰显)。是否有一个我还没有找到的特殊开关来激活它们?

使用 DUnit 9.4(来自 Delphi 2009 或来自 sourceforge Subversion 存储库)和 FastMM4.92

0 投票
5 回答
3324 浏览

delphi - 如何在服务中使用 FastMM4 内存泄漏报告?

如果应用程序作为服务运行, FastMM4 for Delphi 提供的用于将内存泄漏报告到详细文件的相同技术是否有效?当然,最好的做法是先编写单元测试和一个简单的独立应用程序,然后在服务环境之外找到那里的漏洞。

0 投票
5 回答
1139 浏览

delphi - 如何列出所有实例化的对象?

如何使用 FASTMM4 或默认内存管理器列出所有应用程序中的所有实例化对象?

0 投票
4 回答
3040 浏览

delphi - FastMM4 说“块头已损坏”

我有这个讨厌的错误,过去消失了,但现在过了一段时间又回来了。

我创建了两个 TSam 对象(从 TPersistent 派生)并将其加载到一个 TAsmJob 对象(从 TObjectList 派生)。

在运行时,一个表单会创建一个 TStringGrid,然后是创建这两个 SAM 对象的 AsmJob(并在每个对象中从磁盘加载一些数据)。AsmJob 也分配给网格。当表单被销毁时,Grid 通过释放 AsmJob 来处理它,从而释放 TSam 对象。这是问题所在:第一个对象被释放而没有问题,但第二个对象在调用其继承方法(在 Destroy 析构函数中)时死亡。

我在整个程序中使用 FreeAndNil 来释放对象。TSam 对象不是 NIL !!!!!!因此,这是释放对象的第一次尝试。甚至对象内部的数据也是一致的。

该程序的主干如下所示:

我真的不明白我在哪里尝试双重释放或在对象被释放后覆盖它。


编辑:

我得到的一些错误:

  • FastMM 在空闲块扫描操作期间检测到错误。FastMM 检测到一个块在被释放后被修改。

  • FastMM 在空闲块扫描操作期间检测到错误。块头已损坏。

细节:

我在 IDE 中启用了所有“调试”选项,包括“范围检查”。此外,FastMM4 设置为超级积极的调试模式。如果没有 FastMM 或在调试器之外,程序运行得很好——但我知道这并不意味着错误不再存在。实际上,它(可能)工作了一年多,直到我安装了 FastMM。


编辑:

谢谢大家。不,我觉得我正在朝着好的方向前进。

程序的结构更复杂,我只提供了主干来保持原始帖子的小。但见鬼,它已经变大了 :) 所以,这些 TSam 对象用于从磁盘加载数据。每个对象中有一个文件。他们也在做一些处理和数据验证。对于这些 TSam 中的每一个,我还有一个图形对象,它在屏幕上(以图形方式)显示 TSam 对象中包含的数据。TStringGrid 中的每一行也以文本形式显示 TSam 中的数据。

我有一个问题:如果我将程序分成小块以找出错误所在,错误还会出现吗?或者它可能只出现在这个特定的配置中?


回答“如何将 AsmJob 分配给 TStringGrid,以便 TStringGrid 破坏 AsmJob,你能告诉我们吗?”

然后在 TForm.Create (保存网格的表单)的某个地方,我做

在 MyGrid 的析构函数中,我这样做:

0 投票
4 回答
9078 浏览

delphi - 如何从 FastMM 获取堆栈跟踪

我在下面的帖子中注意到,您可以从 FastMM 中获取堆栈跟踪,以显示对象被分配的位置:

如何使用 fastMM 追踪棘手的内存泄漏?

不过,我找不到任何有关如何在 Delphi 2009 中启用此功能的信息。

我已设置ReportMemoryLeaksOnShutdown为 true,所以我得到了基本报告,但我如何获得堆栈跟踪报告?

0 投票
2 回答
1169 浏览

delphi - Delphi - 未释放结构的字符串 [FastMM 管理器]

如果我声明

我运行以下代码:

FastMM 4 内存管理器报告存在内存泄漏(类型:字符串,数据转储:“something bla bla bla”)。但是,如果我在调用dispose它之前将 s1 字符串设置为空,就可以了。

我发现的第二种方法是从记录类型更改为类,然后new我不是创建实例,而是dispose调用instance.Free(). 它无需手动清洁琴弦即可工作。

有没有办法让 Delphi 在我打电话时自动清理我的字符串dispose