テーブルNewRow()が原因でメモリリークが発生する
-
04-07-2019 - |
質問
メモリリークの調査中に、ループ内のテーブルでNewRow()を何度も呼び出すことが原因であることを発見しました。ただし、作成されたDataRowがTable Rowsコレクションに追加されることはなく、Table Rows Countがゼロを超えることはありませんでした。
私の質問は、新しく作成されたDataRowがRowsコレクションに追加されず、NewRowから返されたDataRowが常に同じローカル変数に割り当てられるにもかかわらず、NewRowが呼び出されるたびにメモリを消費する理由です最後の新しい行)。
コードがテーブルに追加されないDataRowを作成する理由の問題を無視してください!
解決
DataRowはDataTableからスキーマを継承するため、DataRowから行を生成したテーブルスキーマへの参照があります。テーブル内の新しい行は切り離された状態です。
これが、GCが新しい未使用の行をそのまま残した理由です。
他のヒント
DataTable.NewRow()は、作成された行をDataTableのRecordManagerに追加します。これが起こる理由は完全にはわかりませんが、これがGCによって解放されない理由です。
DataRowを削除する方法は2つしかないようです:
- テーブルに追加してから削除します。
- DataTable.Clear()を呼び出します。
あなたの2つの問題は関連していると思います。
Table.NewRowは、初期テーブルと同じ列形式の新しいデータ行を作成します。
この新しい行は、table.Rows.Add(newRow)を使用してテーブルに追加する必要があります。ループは決して使用されないオブジェクトを作成するため、メモリを消費します。 詳細については、この記事を参照してください http://msdn.microsoft.com/en- us / library / system.data.datatable.newrow.aspx
newRow = table.NewRow()を作成し、以下のコードでこのnewRowよりも必要ない場合を決定する場合。 1)テーブルにif行を追加します。 2)削除します。メモリリークを防ぎます。
var table = new DataTable();
while (true)
{
var newRow = table.NewRow();
table.Rows.Add(newRow); //Without this 2 rows you will have memory leak.
table.Rows.Remove(newRow);//
}