Delphi:FastMM虚拟内存管理参考?
我最近遇到了一个问题(请参阅我的最后一个问题),这促使我仔细研究了我的 Delphi 应用程序中的内存管理。经过第一次探索后,我有两个问题。
我开始使用 FastMMUsageTracker,并注意到以下内容。当我打开应用程序使用的文件(它还创建表单等...)时,应用程序的可用虚拟内存的变化与“FastMM4 分配的”内存的变化之间存在显着差异。
首先,我对术语有点困惑:为什么会有一些 FastMM 分配的内存和一些“系统分配”(和保留)内存?既然FastMM是内存管理器,为什么系统要负责分配一些内存呢?
另外,如何获得有关已分配该内存的对象/结构的更多详细信息? VM 图表仅用于显示“系统分配”、“系统保留”或“FastMM 分配”的内存量,但没有指向需要该内存的实际对象的链接。例如,是否可以在执行过程中获取类似于 FastMM 在关闭应用程序时生成的报告? FastMM 显然将该信息存储在某处。
作为对我的奖励,如果人们可以推荐有关该主题的良好参考资料(书籍、网站),我也会非常感激。网上有大量信息,但通常都是针对具体情况且面向专家的。
谢谢!
PS:这并不是要查找泄漏,这没问题,只是想更好地理解内存管理并为未来做好准备,因为我们的应用程序使用越来越多的内存。
I had an issue recently (see my last question) that led me to take a closer look at the memory management in my Delphi application. After my first exploration, I have two questions.
I've started playing with the FastMMUsageTracker, and noticed the following. When I open a file to be used by the app (which also creates a form etc...), there is a significant discrepancy between the variation in available virtual memory for the app, and the variation in "FastMM4 allocated" memory.
First off, I'm a little confused by the terminology: why is there some FastMM-allocated memory and some "System-allocated" (and reserved) memory? Since FastMM is the memory manager, why is the system in charge of allocating some of the memory?
Also, how can I get more details on what objects/structures have been allocated that memory? The VM chart is only useful in showing the amount of memory that is "system allocated", "system reserved", or "FastMM allocated", but there is no link to the actual objects requiring that memory. Is it possible for example to get a report, mid-execution, similar to what FastMM generates upon closing the application? FastMM obviously stores that information somewhere.
As a bonus for me, if people can recommend a good reference (book, website) on the subject, it would also be much appreciated. There are tons of info on the net, but it's usually very case-specific and experts-oriented.
Thanks!
PS: This is not about finding leaks, no problem there, just trying to understand memory management better and be pre-emptive for the future, as our application uses more and more memory.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的一些问题很简单。好吧,无论如何,其中之一!
您在 Delphi 中编写的代码只是您的进程中运行的代码的一部分。您可以使用 DLL 形式的第 3 方库,尤其是 Windows API。例如,每当您创建 Delphi 窗体时,其后面都会有许多消耗内存的 Windows 对象。该内存不会由 FastMM 分配,我猜想这就是您问题中所谓的“系统分配”。
然而,如果你想更深入,那么这很快就会变成一个极其复杂的话题。如果您确实想更深入地了解 Windows 内存管理的实现,那么我认为您需要查阅严肃的参考资料。我建议 Mark Russinovich、David Solomon 和 Alex Ionescu 编写的 Windows Internals。
Some of your questions are easy. Well, one of them anyway!
The code that you write in Delphi is only part of what runs in your process. You use 3rd party libraries in the form of DLLs, most notably the Windows API. Anytime you create a Delphi form, for example, there are a lot of windows objects behind it that consume memory. This memory does not get allocated by FastMM and I presume is what is termed "system-allocated" in your question.
However, if you want to go any deeper then this very rapidly becomes an extremely complex topic. If you do want to go deeper into the implementation of Windows memory management then I think you need to consult a serious reference source. I suggest Windows Internals by Mark Russinovich, David Solomon and Alex Ionescu.
您认为 FastMM 从哪里获取要分配的内存?当然,它来自系统。
当您的应用程序启动时,FastMM 从系统获取一块内存。当您请求使用一些内存时(无论是使用 GetMem、New 还是 TSomething.Create),FastMM 会尝试从第一个初始块中将其提供给您。如果那里不够,FastMM 会向系统请求更多(如果可能的话,在一个块中),并将其中的一大块返回给您。当您释放某些内容时,FastMM 不会将该内存返回给操作系统,因为它认为您将再次使用它。它只是将其标记为内部未使用。它还尝试重新对齐未使用的块,使它们尽可能连续,以避免不必要地返回操作系统。 (不过,这种重新调整并不总是可能的;这就是您最终会因多次调整动态数组大小、创建和释放大量对象等而产生内存碎片的地方。)
除了 FastMM 在您的应用程序中管理的内存之外,系统为栈和堆留出空间。每个进程在启动时都会获得一兆堆栈空间,作为放置变量的空间。该堆栈(和堆)可以根据需要动态增长。
当您的应用程序退出时,它分配的所有内存都会释放回操作系统。 (它可能不会立即出现在任务管理器中,但确实如此。)
据我所知还没有。因为 FastMM 将其存储在某个地方并不一定意味着有一种方法可以在运行时从内存管理器外部访问它。您可以查看 FastMMUsageTracker 的源代码,了解如何检索信息(在 RefreshSnapshot 方法中使用 GetMemoryManagerState 和 GetMemoryMap)。 FastMM4 的源代码也可用;您可以查看哪些公共方法可用。
FastMM 自己的文档(以自述文件、FastMM4Options.inc 注释和 FastMM4_FAQ.txt 文件的形式)在某种程度上有助于解释其工作原理以及可用的调试选项(和信息)。
Where do you suppose FastMM gets the memory to allocate? It comes from the system, of course.
When your app starts up, FastMM gets a block of memory from the system. When you ask for some memory to use (whether with GetMem, New, or TSomething.Create), FastMM tries to give it to you from that first initial block. If there's not enough there, FastMM asks for more (in one block if possible) from the system, and returns a chunk of that to you. When you free something, FastMM doesn't return that memory to the OS, because it figures you'll use it again. It just marks it as unused internally. It also tries to realign unused blocks so that they're as contiguous as possible, in order to try not to have to go back to the OS for more needlessly. (This realignment isn't always possible, though; that's where you end up with memory fragmentation from things like multiple resizing of dynamic arrays, lots of object creates and frees, and so forth.)
In addition to the memory FastMM manages in your app, the system sets aside room for the stack and heap. Each process gets a meg of stack space when it starts up, as room to put variables. This stack (and the heap) can grow dynamically as needed.
When your application exits, all of the memory it's allocated is released back to the OS. (It may not appear so immediately in Task Manager, but it is.)
Not as far as I can tell. Because FastMM stores it somewhere doesn't necessarily mean there's a way to access it during runtime from outside the memory manager. You can look at the source for FastMMUsageTracker to see how the information is retrieved (using GetMemoryManagerState and GetMemoryMap, in the RefreshSnapshot method). The source to FastMM4 is also available; you can look and see what public methods are available.
FastMM's own documentation (in the form of the readme files, FastMM4Options.inc comments, and the FastMM4_FAQ.txt file) is useful to some extent in explaining how it works and what debugging options (and information) is available.
有关进程使用的内存的详细映射,请尝试 www.sysinternals.com< 中的 VMMAP< /a> (也是由 Mark Russinovich 合着,在 David 的回答中提到)。这还允许您查看某些位置中存储的内容(选择详细信息行时键入 control-T)。
警告:您的进程使用的内存比您想象的要多得多。您可能需要先阅读这本书。
For a detailed map of what memory a process is using, try VMMAP from www.sysinternals.com (also co-authored by Mark Russinovich, mentioned in David's answer). This also allows you to see what is stored in some of the locations (type control-T when a detail line is selected).
Warning: there is much more memory in use by your process than you might think. You may need to read the book first.