在我的过程中,所有这些没有提及的保留的记忆是什么?

我使用SysInternals中的VMMap来查看WinXP上Win32 C ++进程分配的内存,我看到一堆分配,其中分配内存的一部分被保留但未提交。 据我所知,从我的阅读和testing中,在C ++程序中使用的所有常见内存分配器(例如,malloc,new,LocalAlloc,GlobalAlloc)总是分配完全承诺的内存块。 堆是预留内存的代码的常见示例,但是直到需要时才提交。 我怀疑其中一些块是Windows / CRT堆,但似乎有更多的这些types的块比我预期的堆。 我在这个过程中看到了30个这样的块,大小在64K到8MB之间,而且我知道我的代码永远不会故意调用VirtualAlloc来分配保留的,未提交的内存。

以下是VMMap的几个示例: http ://www.flickr.com/photos/95123032@N00/5280550393/

还有什么会分配这样的内存块,其中大部分是保留的,但没有提交? 我的过程有30堆是否合理? 谢谢。

我想通了 – 这是通过调用malloc分配的CRT堆。 如果使用malloc分配一大块内存(例如,2 MB),它将分配一个确定的内存块。 但是如果你分配更小的数据块(比如说177kb),那么它将保留1MB的内存块,但是只能提交大约你所要求的内容(例如,对于我的177kb请求,这个数据块是184kb)。 释放该小块时,较大的1 MB块不会返回到操作系统。 除4k以外的所有内容均未提交,但全部1 MB仍保留。 如果您再次调用malloc,它将尝试使用该1 MB大块来满足您的请求。 如果使用已经保留的内存无法满足您的请求,它将分配一个新的内存块,这是以前分配的两倍(在我的情况下,它从1 MB到2 MB)。 我不确定这种翻番的模式是否继续。 要真正将释放的内存返回到操作系统,可以调用heapmin。 我认为这会使未来的大分配更有可能取得成功,但是这将全部取决于内存碎片,如果分配失败(?),heapmin也许已经被调用,我不确定。 由于heapmin会释放内存(花费时间),所以会出现性能问题,而malloc则需要在需要时再次从操作系统重新分配内存。 此信息适用于Windows / 32 XP,您的里程可能会有所不同。

更新:在我的测试中,heapmin没有做任何事情。 malloc堆只用于小于512kb的块。 即使malloc堆中有连续可用空间的MB,也不会在超过512kb的请求中使用它。 在我的情况下,这个被释放的,未被使用但保留的malloc内存咀嚼了我的进程的大部分2GB地址空间,最终导致内存分配失败。 而且,由于heapmin不会将内存返回到操作系统,除了重新启动我的进程或编写我自己的内存管理器之外,我还没有找到任何解决此问题的方法。

他们可能是加载到你的过程中的DLL? DLL(和可执行文件)被内存映射到进程地址空间。 我相信这最初只是预留空间。 该空间由文件本身(至少在最初)支持,而不是页面文件。

只有实际触及的代码才会被分页。如果我正确地理解了术语,那就是提交的时候。

您可以通过在调试器中运行您的应用程序并查看已加载的模块,并将其位置和大小与您在VMMap中看到的内容和大小进行比较来确认。

每当在应用程序中创建一个线程时,线程的调用堆栈的地址空间中将保留一定的(可配置的)内存量。 除非你的线程真的需要所有的内存,否则不需要提交所有的保留内存。 所以只有一部分需要承诺。

如果需要超过承诺的内存量,将有可能获得更多的系统内存。

实际的考虑是保留的内存是堆栈大小的硬限制,这减少了应用程序可用的地址空间。 但是,通过只提交一部分储备,我们不必从系统中消耗相同数量的内存直到需要。

因此,每个线程都可能有一部分保留未提交的内存。 我不确定在这种情况下页面的类型。