0

std::ostringstream オブジェクトがプロセス メモリを消費し続ける状況 (Win32 上) に遭遇しました。この C++ フラグメントを見てください。

int main(void)
{
    std::ostringstream cOutputLogStream;

    // Random long string
    std::string sTest = "jkspoiauyeraspfoiusdfsdfekgpweojkgpwoekpokgkpgeopoegwj";

    std::string sEmpty = "";

    int n = 0;
    int looper = 0;

    while (n++ < 100000)
    {
        while (looper++ < 45)
        {
            cOutputLogStream  <<  s;
        }

        cOutputLogStream.str(sEmpty);
        cOutputLogStream.clear();

        // This should give the heap manager a chance to consolidate
        // fragmented memory blocks
        Sleep(1);
    }
}

内側の while() ループの実行中に、タスク マネージャーでプロセスのメモリ使用量を観察すると、継続的な上昇傾向が見られますが、最終的には横ばいになります。ただし、この平準化は、エラー std::bad_alloc が繰り返しスローされると同時に発生します。これは、ヒープ メモリが使い果たされたか、要求されたサイズのブロックが連続した領域で使用できないことを示しています。

他の誰かが ostringstream オブジェクトでこのリーク現象を経験したことがありますか? また、この不安定なものの代わりに他の代替オブジェクトを利用できますか?

どうもありがとう!

4

1 に答える 1

2

このコードがどのように問題を再現できるかわかりません。ルーパーが 45 までインクリメントした後、メモリの消費はほぼ完了しているはずです。

一般的な診断は、プログラムが利用可能なすべての仮想メモリを消費することはめったにないということです。文字列ストリーム バッファを格納するのに十分な大きさの連続したバイトのチャンクをヒープ内で見つけると、最初に停止します。これはアドレス空間のフラグメンテーションと呼ばれ、それに対してできることは何もありません。Sleep() 呼び出しは確かに何も役に立ちません。割り当てられたヒープ ブロックを統合するには、ガベージ コレクターが必要です。

もう 1 つの非常に標準的なトラップは、TaskMgr.exe を使用してメモリ使用量を診断することです。通常、RAM にマップされている仮想メモリの量であるワーキング セットが表示されます。これは通常、プログラムが消費する仮想メモリの量のほんの一部であり、プログラムが消費した仮想メモリの量を正確に測定することはできません。または、アドレス空間の断片化について何か教えてください。

SysInternals の VMMap ユーティリティは、プログラムが仮想メモリをどのように使用しているかを表示できます。

于 2010-07-14T16:13:24.033 に答える