因此,我有一个 native C++应用程序,它需要长时间跟踪很多事情。当任务管理器说进程到达800到1200 MB内存之间的某个地方时,内存用完了,而限制应该是2GB。
我终于对我对进程运行VMMap时发生的事情有了一个线索,但这给了我更多的问题。我发现:
这些子块对的一个示例:(不是我的应用程序,但是想法是相同的)
http://www.flickr.com/photos/95123032@N00/5280550393
好像当一个私有(private)数据块完全提交时,会分配一个新块(通常是前一个最大块的大小或两倍)。听起来很公平。但是,我已经看到3个块,每个块都超过100MB,而提交的块少于30MB。我的应用程序不应以可能的方式运行(即用完400MB,然后在几个小时内缩小300MB)。
据我所知,“大小”是已分配的虚拟内存地址空间的实际数量。 “已提交”是实际使用的“大小”的数量(即通过调用new/malloc)。如果确实如此,那么为什么“大小”和“已提交”之间存在如此巨大的差异?为什么要分配大小为数百兆字节的块?
有点奇怪的是,在Windows 7上运行时,行为是完全不同的。而在2003 Server上,应用程序使用私有(private)数据,而在Windows 7上,应用程序使用Heap。所以为什么?为什么VMMap在2003年主要显示私有(private)数据使用情况,而在7年主要显示堆使用情况?有什么不同?好区别是我无法使用VMMap中的“堆分配...”按钮来查看所有私有(private)数据的分配位置。
我开始怀疑是否过度使用std::string会导致这个问题,因为我在对中识别的字符串(上述)主要由存储在std::string中的字符串组成,这些字符串经常被创建和销毁(这意味着很多)内存分配/取消分配)。我将所有可能的转换为使用字符数组或使用内存池中的内存,但这似乎没有任何效果。我所有其他经常被新删除的对象都已经拥有了自己的内存池。
我还发现了低碎片堆的问题,因此我尝试启用它,但也没有任何改变。我想这是因为Windows 2003实际上并未正确使用堆。 VMMap显示低碎片堆已启用,但是由于实际上并未使用它(即它使用的是Private Data),因此实际上没有任何区别。
实际上似乎正在发生的事情是那些子块对正在分割大型私有(private)数据块,这导致操作系统分配新的块。最终,碎片变得如此糟糕,以至于即使有很多未提交的空间,碎片也似乎都无法使用,并且进程耗尽了内存。
所以我的问题是:
有没有一种方法可以使Windows Server 2003改为使用堆内存?
如果是这样,那将完全改善我的状况吗?
最佳答案
私有(private)数据只是所有未在两个或多个进程之间共享的内存的分类。堆,重定位的dll页,进程中所有线程的堆栈,未共享的内存映射文件等都属于私有(private)数据类别。
当以下条件之一为真时,操作系统(通过VirtualAlloc)对内存的请求将失败:
除此之外,堆分配可能由于其自身的原因而失败,例如,在扩展过程中,它们实际上将尝试获取更多内存,从而触发扩展的分配请求的大小-如果失败,则它们可能只是失败-尽管实际请求的大小可能可通过VirtualAlloc获得。
很少会累积内存的东西是,
关于c++ - 什么在Windows Server 2003上使用了这么多未提交的 “private data”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15708040/