データベースから一連のレコードを抽出するデータ エクスポート プログラムに取り組んできました。手順の 1 つは、RTF テキスト文字列をプレーン テキストに変換することであり、実行時にユーザー オブジェクトのメモリ リークが発生しました。タスク マネージャーが表示する列の 1 つは「ユーザー オブジェクト」です。これが 10,000 に達すると、プログラムは割り当て領域を使い果たし、プログラムは「ウィンドウ ハンドルの作成エラー」でエラーになります。
これは、メソッドの最後でオブジェクトを破棄しなかったために発生していました。
私の質問は、なぜ C#/.net が私のためにそれを処分しなかったのですか?
リークを再現するコードの簡単なサンプルを次に示します。コードを Winforms アプリケーションに挿入し、ボタンを押して、メモリの浪費をループさせます。
private void wasteMemory()
{
System.Windows.Forms.RichTextBox rtfBox = new System.Windows.Forms.RichTextBox();
//RTF text that reads "Hello World"
rtfBox.Rtf = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}} {\\colortbl ;\\red0\\green0\\blue0;} \\viewkind4\\uc1\\pard\\cf1\\fs29 Hello World} ";
//If line below is commented out, User Objects grow out of control.
//rtfBox.Dispose();
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 1; i < 100000; i++)
{
wasteMemory();
}
}
メソッドのスコープ内で作成されたオブジェクトは、メソッドが完了すると破棄されるというのが私の理解です。rtfBox が破棄されることを期待していましたが、そうではありません。