4

文字列のマップを使用するかなり複雑なデータオブジェクトがあります

typedef std::map<std::string, unsigned int> Event;
typedef std::pair<double, Event> EventGroup;
std::vector<EventGroup> eventVector;

これは、常にバックグラウンドで実行され、着信メッセージをリッスンするプログラムです。マップに任意の数の文字列を含めることができる新しい EventGroup が入るたびに、それをベクターに追加します。

// New data came in
eventVector.push_back(newEventGroup);

時々、このベクトルを消去します

//Flush some of the data because it's old
// it's been determined that the index to erase at is flushIndex
eventVector.erase(eventVector.begin(), eventVector.begin()+flushIndex);

通常、これはデータの最初の 5% になる傾向があります。

私が気づいたのは、メモリリークがあるようだということです。メモリ使用量は 50 MB 前後から始まりますが、遅くなりすぎてクラッシュする前に 1 GB 近くになります。消去にはコストがかかると聞きましたが、これがメモリリークの原因になるのでしょうか? マップで使用されているメモリを解放する方法がありませんか?

4

1 に答える 1

4

カスタム型がどのように機能するか、またはどのように見えるかを知らなければ (メモリ リークが発生していませんか?)、それを言うのは困難です。ただし、ベクターから要素を消去しても、実際にはメモリが解放されないことに注意してください。ベクターが既に割り当てている領域が、そのベクターに追加されたさまざまな要素に使用できるようになります。つまり、ベクトルの予約済みスペースは変わりません。

したがって、ベクトルを数百万要素に増やし、それらの 90% を消去し、大量のメモリが返されることを期待すると、がっかりするでしょう。ベクトルによって予約されたメモリを解放する方法(破棄されるまで何も返さない)は、スワップイディオムを行うことです:

std::vector<EventGroup>(eventVector).swap(eventVector);

ここでコピー コンストラクターがどのように機能するかについての正確な詳細は覚えていません。これを行った場合とまったく同じように動作するはずです。

std::vector<EventGroup>(eventVector.begin(), eventVector.end()).swap(eventVector);

これがどれだけのスペースを消費するかはまだ制御できませんが、大量のスペースを解放し、それが長期間解放されたままになる場合...これにより、不明な量のメモリがシステムに返されます。

これはコストのかかる操作であることに注意してください (これが std::vector が単にそれを実行しない理由です) ので、必要な場合にのみ実行してください。

于 2012-05-02T18:56:52.563 に答える