によって報告されたメモリ使用量 (RES) に関して、Linux の興味深い動作に気付きましたtop
。ヒープに数百万のオブジェクトを割り当てる次のプログラムを添付しました。各オブジェクトには約 1 キロバイトのバッファーがあります。std::list
これらのオブジェクトへのポインタは、 またはによって追跡されますstd::vector
。私が気付いた興味深い動作は、 を使用するstd::list
と、 によって報告されるメモリ使用量top
がスリープ期間中に変化しないことです。ただし、 を使用するstd::vector
と、スリープ中にメモリ使用量が 0 近くまで低下します。
私のテスト構成は次のとおりです。
Fedora Core 16
Kernel 3.6.7-4
g++ バージョン 4.6.3
私がすでに知っていること:
1. std::vector は、必要に応じて (サイズを 2 倍にして) 再割り当てします。
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);
}