0

私のC ++プログラムで私が使用する

* m_Map= new map<int, list<object> >();
delete(m_Map);
m_Map->erase(TxId);

マップに 1000000 要素を追加し、プロセスのメモリ使用量をループで時々チェックしました

for(int x=1;x<=1000000;x++){
    m_Map->emplace(txId, OBject);
    if(x%100000==0) {
        process_mem_usage(vm, rss);
        cout << "after add a key  VM: " << vm << "; RSS: " << rss << endl;
        }
    }

次に、マップから要素を 1 つずつ消去して、プロセスの RSS メモリ使用量を再度出力します。

 for(int x=1;x<=1000000;x++){
      m_Map->erase(x);
      if(x%100000==0) {
           process_mem_usage(vm, rss);
           cout << "after earse a key VM: " << vm << "; RSS: " << rss << endl;
        }
 }

このメモリ使用関数を使用して

void process_mem_usage(double& vm_usage, double& resident_set)
{
   using std::ios_base;
   using std::ifstream;
   using std::string;

   vm_usage     = 0.0;
   resident_set = 0.0;

   // 'file' stat seems to give the most reliable results
   //
   ifstream stat_stream("/proc/self/stat",ios_base::in);

   // dummy vars for leading entries in stat that we don't care about
   //
   string pid, comm, state, ppid, pgrp, session, tty_nr;
   string tpgid, flags, minflt, cminflt, majflt, cmajflt;
   string utime, stime, cutime, cstime, priority, nice;
   string O, itrealvalue, starttime;

   // the two fields we want
   //
   unsigned long vsize;
   long rss;

   stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
               >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
               >> utime >> stime >> cutime >> cstime >> priority >> nice
               >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest

   stat_stream.close();

   long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
   vm_usage     = vsize / 1024.0;
   resident_set = rss * page_size_kb;
}

私は本当に理解できないこの結果を思いついた。

 Initially VM: 12660; RSS: 1120
after add a key  VM: 28240; RSS: 16960
after add a key  VM: 43816; RSS: 32536
after add a key  VM: 59524; RSS: 48112
after add a key  VM: 75100; RSS: 63688
after add a key  VM: 90676; RSS: 79264
after add a key  VM: 106384; RSS: 95104
after add a key  VM: 121960; RSS: 110680
after add a key  VM: 137672; RSS: 126256
after add a key  VM: 153248; RSS: 141832
after add a key  VM: 168824; RSS: 157408
after earse a key VM: 168824; RSS: 157408
after earse a key VM: 168824; RSS: 157408
after earse a key VM: 168824; RSS: 157408
after earse a key VM: 168824; RSS: 157408
after earse a key VM: 168824; RSS: 157408
after earse a key VM: 168824; RSS: 157408
after earse a key VM: 168824; RSS: 157408
after earse a key VM: 168824; RSS: 157408
after earse a key VM: 168824; RSS: 157408
after earse a key VM: 168824; RSS: 157408


after destroying the map VM: 12672; RSS: 1536

私が感じているのは、マップからキーと値のペアを削除するときにメモリを解放する必要があるということですが、ご覧のとおり、最終的にマップを削除(解放)するまでメモリは解放されません

delete(m_Map);

c++でそれがどのように起こるかを説明できる人がいます.c++ map::emplace,erase関数のドキュメントを見ましたが、これについての手がかりはありません..

4

1 に答える 1

0

プロセスには 2 つの異なるメモリ アロケータがあると考えることができます。カーネルからメモリを要求すると、最初の 1 つのアロケータが使用されます ( sbrk(2)mmap(2))。2 つ目は、最初のアロケータから取得したメモリを C++ コードからのリクエストにスライスする usespace アロケータです。

new/を実行するとmalloc、メモリの 2 番目のアロケータが要求されます (最初のアロケータを使用して、要求を満たすことができない場合にカーネルからより多くのメモリを要求できます)。delete/ - を実行するfreeと、最初のアロケーターとカーネルにメモリを返すことができる (しかし必須ではありません!) 2 番目のアロケーターにメモリを放棄します。

newしたがって、 , malloc/deleteを実行freeすると、すぐにRSSorが変更されるという意味ではありませんVM

于 2016-11-29T10:16:41.047 に答える