STL容器的内存消耗

时间:2012-08-07 07:42:42

标签: c++ memory-management stl map vector

我正在开发一个我计划使用几个STL容器的应用程序。如果内存消耗达到阈值,应用程序将采取某些步骤。为此,我需要对STL容器使用的内存量进行接近准确的计算。

vector<string> StringList
map<string, int> mapstring

这是我估算记忆的方式:

对于StringList的大小,循环遍历向量的所有元素并继续添加字符串大小。

string size = sizeof(string) + string.capacity()*sizeof(char)

然后最后添加到此sizeof(StringList);

对于mapstring的大小,循环遍历容器的所有键并继续添加字符串大小,然后添加int的大小mapstring.size()*sizeof(int)。然后最后添加到此sizeof(mapstring);

我想更好的方法是指定自己的分配器类并跟踪其中的内存使用情况,但写一个可能是非平凡的。这个估计看起来不错吗?

2 个答案:

答案 0 :(得分:11)

std::vector<element>通常需要3个机器字 + sizeof(element)* capacity()内存。对于典型的实现,开销包括指向向量的开始,结束和当前大小的指针。元素本身存储在连续的内存中。 capacity()通常可以容纳最多两倍的实际元素数。

std::map<element, int>通常需要大约2个机器字总计 + 3个机器字 每个元素 + [sizeof(element) + sizeof(int)] * num_elements of memory。对于典型的实现,开销包括指向存储元素的指针。元素本身存储在二叉树中,指向其父节点和两个子节点。

根据这些经验法则,您需要知道的是每个字符串的平均字符数以及知道总内存消耗的字符串总数。

答案 1 :(得分:11)

对于std::vectorstd::string,容量而不是大小 是一个更好的近似。对于基于节点的容器(std::set, 等),你想要乘以节点的数量(大致是数量) elements)乘以每个节点的大小。但是,这只是准确的 分配器不为节点使用优化池分配器。

但是,如果你真的想知道正在使用多少内存,a 更好的策略是取代全球operator newoperator delete,并跟踪实际分配情况。更 准确的是替换mallocfree。在形式上,事实并非如此 允许,但在实践中,我从未遇到过实施的地方 它不起作用。另一方面,如果您替换mallocfree, 你必须自己实现实际的内存管理。如果你 替换operator newoperator delete,您可以使用mallocfree,这使得它相当微不足道。

另请注意,每个分配都有一些固定的开销。一个100000 每个10字节的分配将消耗更多的内存 10个分配,每个100000字节。