6

type のフィールドを持つクラスがありますunordered_map。アプリケーションでこのオブジェクトのインスタンスを 1 つ作成し、shared_ptr. オブジェクトは非常にメモリを消費するので、使い終わったらすぐに削除したいと考えています。ただし、ポインタをリセットしても、オブジェクトが占有していたメモリのごく一部しか解放されません。オブジェクトが占有しているすべてのメモリをプログラムに解放させるにはどうすればよいですか?

次のモック プログラムは、私の問題を再現します。ガベージを出力する for ループは、 で使用されるメモリを観察するのに十分な時間を与えるためだけに存在しtopます。デストラクタは の直後に呼び出されreset()ます。また、直後にメモリ使用量が約2GBから1.5GBに減少。

#include <iostream>
#include <memory>
#include <unordered_map>

using namespace std;

struct A {
  ~A() {
    cerr << "Destructor" << endl;
  }

  unordered_map<int, int> index;
};

int main() {
  shared_ptr<A> a = make_shared<A>();
  for (size_t i = 0; i < 50000000; ++i) {
    a->index[2*i] = i + 3;
  }

  // Do some random work.
  for (size_t i = 0; i < 3000000; ++i) {
    cout << "First" << endl;
  }

  a.reset();

  // More random work.
  for (size_t i = 0; i < 3000000; ++i) {
    cout << "Second" << endl;
  }
}

コンパイラ: g++ 4.6.3。

4

2 に答える 2

5

GCC の標準ライブラリには「STL メモリ キャッシュ」がありません。デフォルトの構成 (ほとんどの人が使用) では、 andを呼び出すstd::allocatorだけで、 newanddeleteを呼び出すだけです。実装 (通常はシステムの C ライブラリから取得されます) は、メモリを OS に返すかどうかを決定します。仮想メモリのない組み込み/制約付きシステムを使用している場合 (またはオーバーコミットをオフにしている場合) を除き、おそらくそれを返したくないでしょう。ライブラリに必要なことをさせてください。mallocfreemalloc

OS はメモリを元に戻す必要はありません。問題なく他のアプリケーションにギガバイトの仮想メモリを割り当てることができます。人々がメモリを返す必要があると考えるときはいつでも、それは通常、最新の OS が仮想メモリを処理する方法を理解していないためです。

C ライブラリに強制的にメモリを OS に返させたい場合、C ライブラリはそのための非標準フックを提供している可能性がありますmalloc_trim(0)。ただし、次回より多くのメモリを割り当てる必要がある場合は、OS からメモリを取得する必要があるため、プログラムが遅くなる可能性があります。詳細については、 https://stackoverflow.com/a/10945602/981959 (およびその他の回答) を参照してください。

于 2013-06-19T20:46:20.080 に答える
4

アプリケーションがメモリを解放して OS に戻すという保証はありません。アプリケーションで引き続き使用できますが、OS は、アプリケーションが終了するまで、一般的な使用のためにそれを再利用しない場合があります。

于 2013-06-19T19:22:49.733 に答える