4

我最近遇到了一个问题(请参阅我的最后一个问题),这让我仔细研究了我的 Delphi 应用程序中的内存管理。在我第一次探索之后,我有两个问题。

我已经开始使用 FastMMUsageTracker,并注意到以下内容。当我打开一个应用程序使用的文件(它还创建一个表单等)时,应用程序可用虚拟内存的变化与“FastMM4 分配”内存的变化之间存在显着差异。

首先,我对术语有点困惑:为什么会有一些 FastMM 分配的内存和一些“系统分配”(和保留)的内存?既然 FastMM 是内存管理器,那为什么系统要负责分配一些内存呢?

另外,我怎样才能获得有关哪些对象/结构已分配该内存的更多详细信息?VM 图表仅用于显示“系统分配”、“系统保留”或“FastMM 分配”的内存量,但没有链接到需要该内存的实际对象。例如,是否有可能在执行过程中获得类似于 FastMM 在关闭应用程序时生成的报告?FastMM 显然将这些信息存储在某处。


作为对我的奖励,如果人们可以推荐有关该主题的良好参考资料(书籍,网站),我将不胜感激。网络上有大量信息,但通常是针对特定案例和面向专家的。

谢谢!

PS:这不是寻找泄漏,那里没有问题,只是试图更好地理解内存管理并为未来抢占先机,因为我们的应用程序使用越来越多的内存。

4

3 回答 3

3

你的一些问题很简单。好吧,无论如何,其中之一!

为什么会有一些 FastMM 分配的内存和一些“系统分配”(和保留)的内存?既然 FastMM 是内存管理器,那为什么系统要负责分配一些内存呢?

您在 Delphi 中编写的代码只是您的进程中运行的代码的一部分。您以 DLL 的形式使用第 3 方库,尤其是 Windows API。例如,每当您创建一个 Delphi 表单时,它背后都有很多消耗内存的 windows 对象。FastMM 不会分配此内存,我认为这就是您的问题中所谓的“系统分配”。

但是,如果您想更深入,那么这很快就会成为一个极其复杂的话题。如果您确实想更深入地了解 Windows 内存管理的实现,那么我认为您需要查阅一个严肃的参考资料。我推荐Mark Russinovich、David Solomon 和 Alex Ionescu 的Windows Internals

于 2011-03-28T18:24:18.603 回答
2

首先,我对术语有点困惑:为什么会有一些 FastMM 分配的内存和一些“系统分配”(和保留)的内存?既然 FastMM 是内存管理器,那为什么系统要负责分配一些内存呢?

您认为 FastMM 在哪里获取要分配的内存?当然,它来自系统。

当你的应用启动时,FastMM 从系统中获取一块内存。当您要求使用一些内存时(无论是使用 GetMem、New 还是 TSomething.Create),FastMM 会尝试从第一个初始块中将其提供给您。如果那里还不够,FastMM 会向系统请求更多(如果可能,在一个块中),并将其中的一部分返回给您。当你释放某些东西时,FastMM 不会将该内存返回给操作系统,因为它认为你会再次使用它。它只是在内部将其标记为未使用。它还尝试重新对齐未使用的块,使它们尽可能连续,以便尽量不必返回操作系统进行更多不必要的操作。(但是,这种重新调整并不总是可能的;这就是您最终会因动态数组的多次调整大小而导致内存碎片的地方,

除了 FastMM 在您的应用程序中管理的内存之外,系统还会为堆栈和堆留出空间。每个进程在启动时都会获得一兆的堆栈空间,作为放置变量的空间。这个栈(和堆)可以根据需要动态增长。

当您的应用程序退出时,它分配的所有内存都会释放回操作系统。(它可能不会立即出现在任务管理器中,但确实如此。)

例如,是否有可能在执行过程中获得类似于 FastMM 在关闭应用程序时生成的报告?

据我所知,不是。因为 FastMM 将它存储在某处并不一定意味着有一种方法可以在运行时从内存管理器外部访问它。您可以查看 FastMMUsageTracker 的源代码以了解如何检索信息(在 RefreshSnapshot 方法中使用 GetMemoryManagerState 和 GetMemoryMap)。FastMM4 的源代码也可用;您可以查看并查看可用的公共方法。

FastMM 自己的文档(以自述文件、FastMM4Options.inc 注释和 FastMM4_FAQ.txt 文件的形式)在一定程度上有助于解释它的工作原理以及可用的调试选项(和信息)。

于 2011-03-28T19:05:04.083 回答
0

有关进程正在使用的内存的详细地图,请尝试来自www.sysinternals.com的 VMMAP (也由 Mark Russinovich 合着,在 David 的回答中提到)。这还允许您查看某些位置中存储的内容(选择详细信息行时键入 control-T)。

警告:您的进程使用的内存比您想象的要多得多。您可能需要先阅读这本书。

于 2011-03-28T19:04:18.560 回答