我注意到 Linux 中关于内存使用 (RES) 报告的一些有趣行为top
。我附上了以下程序,它在堆上分配了几百万个对象,每个对象都有一个大约 1 KB 的缓冲区。指向这些对象的指针由 astd::list
或 a跟踪std::vector
。我注意到的有趣行为是,如果我使用 a std::list
,则报告的内存使用情况top
在睡眠期间永远不会改变。但是,如果我使用std::vector
,则在这些睡眠期间内存使用量将降至接近 0。
我的测试配置是:
Fedora Core 16
Kernel 3.6.7-4
g++ version 4.6.3
我已经知道:
1. std::vector 将根据需要重新分配(使其大小加倍)。
2. std::list (我相信)一次分配它的元素 1
3. std::vector 和 std::list 都默认使用 std::allocator 来获取它们的实际内存
4. 程序没有泄漏; valgrind 已声明不可能发生泄漏。
我感到困惑的是:
1. std::vector 和 std::list 都在使用 std::allocator。即使 std::vector 正在执行批量重新分配,std::allocator 不会以几乎相同的安排将内存分配给 std::list 和 std::vector 吗?这个程序毕竟是单线程的。
2. 我在哪里可以了解 Linux 的内存分配行为。我听说过有关 Linux 将 RAM 分配给进程即使在它释放它之后仍保留它的声明,但我不知道这种行为是否得到保证。为什么使用 std::vector 会对这种行为产生如此大的影响?
非常感谢您阅读本文;我知道这是一个非常模糊的问题。我在这里寻找的“答案”是如果这种行为是“定义的”,我可以在哪里找到它的文档。
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <vector>
#include <list>
#include <iostream>
#include <memory>
class Foo{
public:
Foo()
{
data = new char[999];
memset(data, 'x', 999);
}
~Foo()
{
delete[] data;
}
private:
char* data;
};
int main(int argc, char** argv)
{
for(int x=0; x<10; ++x)
{
sleep(1);
//std::auto_ptr<std::list<Foo*> > foos(new std::list<Foo*>);
std::auto_ptr<std::vector<Foo*> > foos(new std::vector<Foo*>);
for(int i=0; i<2000000; ++i)
{
foos->push_back(new Foo());
}
std::cout << "Sleeping before de-alloc\n";
sleep(5);
while(false == foos->empty())
{
delete foos->back();
foos->pop_back();
}
}
std::cout << "Sleeping after final de-alloc\n";
sleep(5);
}