我正在努力更好地理解Windows堆为什么会像它那样工作。考虑以下非常简单的程序:
#include <vector>
#define NUM_ALLOCS 10000000
int _tmain(int argc, _TCHAR* argv[])
{
for (int iteration=0; iteration<10000; ++iteration) {
std::vector<unsigned char *> buffer;
buffer.reserve(NUM_ALLOCS);
for (int i=0;i<NUM_ALLOCS;++i) {
buffer.push_back(new unsigned char);
}
for (int i=0;i<NUM_ALLOCS;++i) {
delete buffer[i];
}
}
return 0;
}基本上,这是一个循环,每次迭代都分配大量1字节块,然后释放它们。当然,这个程序的内存使用量在分配缓冲区时会增加,然后在释放缓冲区时下降。
我在Windows 64位上看到的行为是,峰值内存使用量(由任务管理器或vmmap报告)随着时间的推移大致保持不变,而报告的最低内存使用量则一直增长到接近峰值内存使用量。
在Windows 7 64位上,报告的最低内存使用量不会随时间增长.
编辑:我已经在两台具有8GB/4GB RAM的Windows Vista 64位计算机和一台4 GB RAM的Windows 7 64位计算机上进行了测试。我已经测试了8GB的机器的低内存和高内存使用的情况。
编辑:我用Visual 2005和2010构建了上面的示例,结果是相同的。
这个例子并没有做任何有用的事情,但是内存使用情况与我的一个程序类似(尽管压缩得很紧),我已经尝试找出为什么它使用的内存比实际的要多得多。据我所知,内存由堆管理器保存。
有人对堆机制有任何深入的了解吗?,我需要做一些额外的事情来说服堆管理器完全释放使用过的堆内存吗?我是否应该使用其他策略,比如创建一个单独的堆,然后销毁它?
如有任何意见或见解,敬请见谅!
发布于 2010-12-17 15:59:11
会不会是低碎裂堆
在我看来,我在某个地方读到了LFH在Windows 7上是默认启用的。然而,快速搜索并没有显示确认,所以我可能错了。
不过,有一种简单的检查方法。对从HeapQueryInformation获得的句柄调用GetProcessHeap,并比较不同系统上的结果。
发布于 2010-12-17 09:35:11
你在记忆压力下试过这个吗?除非有别的东西需要,否则释放内存是没有意义的。
发布于 2011-01-27 00:13:25
atzz在正确的轨道上,但这种行为将发生在任何堆中--当您第一次调用具有一个字节大小的"new“时,堆将分配一个”桶“并预先分配某个内存块(可能是页面大小的几倍,4K);这样,当随后出现相同大小的分配时,它可以非常迅速地给您内存。
此外,当您调用delete时,它只是将该区域标记为未分配,但将其保留在周围,以防您以后需要一个类似大小的新对象。
如果Heap Manager按照您的描述操作,它将运行得非常慢,因为它必须不断地询问内核,“您能给我另一个字节吗?”还有“请把这个拿出来!”(事实上,这是不可能的,因为您可以要求内核给您的最小分配是页面大小,我记得)
https://stackoverflow.com/questions/4468958
复制相似问题