アプリで重大なメモリ リークが発生しています。メソッドの1つでローカルのconcurrentBagコレクションに追加したすべてのデータは収集されませんでした。
この単純なコードは、私がそれをどのように使用するかを示しています:
void Main()
{
var l = new List<int>(){1,2,3,4};
Func(l);
l.Clear();
l=null;
}
void Func(List<int> list)
{
var bag = new ConcurrentBag<int>();
Parallel.ForEach(list, k=> bag.Add(++k));
list.Clear();
foreach(int i in bag) //I know, I doing it wrong.
{
list.Add(i);
}
}
私が期待すること: バッグが作成され、メソッド「Func」で破棄されます。
私が見ているもの: バッグは破棄されず、Parallel.ForEach で作成されたすべてのスレッドを保持し、追加したすべてのデータを保持します。=(
さて、リストに追加するときに、「TryTake」を使用してバッグからアイテムを削除できます。しかし、空のバッグはまだメモリに保持されています。
現在、ConcurrentBag の代わりに List を使用して問題を解決しています。しかし、これを記憶プロファイラーで見たので、よく眠れません。私の英語でごめんなさい=)
アップデート
メソッド「Func」を変更します。
void Func(List<int> list)
{
var bag = new ConcurrentBag<int>();
Parallel.ForEach(list, k=> bag.Add(++k));
list.Clear();
int i;
while(bag.TryTake(out i))
{
list.Add(i);
}
bag = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
次に、VS でプロジェクトを作成し、プログラムをコンパイルして実行します。このインスタンス グラフは、プログラムがすべての作業を完了してから 10 分後に収集したメモリ スナップショットから ".Net Memory Profiler 4.0" によって作成されました。
http://xmages.net/storage/10/1/0/f/d/upload/4c67f305.jpg (申し訳ありませんが、画像を投稿できません)