標準テンプレート ライブラリを多用する C++ (VS2010) で記述されたマルチスレッド Win32 サービスがあります。プログラムのビジネス ロジックは適切に動作しますが、タスク マネージャー (またはリソース マネージャー) を見ると、プログラムはふるいのようにメモリ リークを起こしています。
1 秒あたり平均約 16 の同時リクエストのテスト セットがあります。プログラムを最初に起動すると、1.5Mb 程度の RAM を消費します。完全なテスト実行 (12 ~ 15 分かかります) の後、メモリ消費量は 12Mb 近くになります。通常、これは一度実行して終了するプログラムでは問題になりませんが、このプログラムは継続的に実行することを目的としています。本当に悪い。
問題を絞り込むために、250 ミリ秒ごとに 1 回の割合でワーカー スレッドをスピンオフする非常に小さなテスト アプリケーションを作成しました。ワーカー スレッドはマップを作成し、疑似乱数データを入力してマップを空にし、終了します。このプログラムも同様にメモリリークを起こしますので、STL が期待通りにメモリを解放しないことが問題だと思います。
リークを検索するために VLD を試してみたところ、修正したいくつかが見つかりましたが、それでも問題は残ります。Hoard を統合しようとしましたが、実際には問題が悪化しました (適切に統合していない可能性がありますが、方法がわかりません)。
そこで、次の質問をしたいと思います。マルチスレッド環境で STL を使用してメモリ リークしないプログラムを作成することは可能ですか? この 1 週間で、私はこのプログラムに 200 以上の変更を加えました。変更の結果をプロットしましたが、それらはすべて同じ基本プロファイルを持っています。このアプリケーションの開発を非常に簡単にした STL の利点をすべて削除する必要はありません。時代遅れになったようにメモリをリークすることなく、このアプリを動作させる方法についての提案を心から感謝します.
助けてくれてありがとう!
PS 検査/個人的な教育のために、メモリテストのコピーを投稿しています。
#include <string>
#include <iostream>
#include <Windows.h>
#include <map>
using namespace std;
#define MAX_THD_COUNT 1000
DWORD WINAPI ClientThread(LPVOID param)
{
unsigned int thdCount = (unsigned int)param;
map<int, string> m;
for (unsigned int x = 0; x < 1000; ++x)
{
string s;
for (unsigned int y = 0; y < (x % (thdCount + 1)); ++y)
{
string z = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
unsigned int zs = z.size();
s += z[(y % zs)];
}
m[x] = s;
}
m.erase(m.begin(), m.end());
ExitThread(0);
return 0;
}
int main(int argc, char ** argv)
{
// wait for start
string inputWait;
cout << "type g and press enter to go: ";
cin >> inputWait;
// spawn many memory-consuming threads
for (unsigned int thdCount = 0; thdCount < MAX_THD_COUNT; ++thdCount)
{
CreateThread(NULL, 0, ClientThread, (LPVOID)thdCount, NULL, NULL);
cout
<< (int)(MAX_THD_COUNT - thdCount)
<< endl;
Sleep(250);
}
// wait for end
cout << "type e and press enter to end: ";
cin >> inputWait;
return 0;
}