web-dev-qa-db-ja.com

Datatable.Dispose()はそれをメモリから削除しますか?

私は非常に単純なコードを調べていて、datatableのdispose()の結果を見るのに行き詰まっています

以下はコードです

DataTable dt= new Datatable();
SqlCommand Cmd = new SqlCommand("sp_getData",SqlCon);
SqlCommand.CommandType= CommandType.StroedProcedure;
SqlCon.Open();
sqlDataReader dr=  cmd.ExecuteReader();
dt.Load(dr);
SqlCon.Close();
grdView.DataSource =dt;
dt.Dispose() // Here I dispose the table as it is no use for me & wanna memory free from this

しかし、データテーブルを破棄した後でも、RowCount = 10kが表示されていることがわかりました。

Dispose()メソッドはメモリを解放せず、オブジェクトをnullにしませんか?

どうすればそれをnullにするか、このオブジェクトが占有しているメモリを解放できますか?

9
Rajeev Kumar

DataSetDataTableには実際には管理されていないリソースがないため、Dispose()は実際にはあまり機能しません。 DataSetおよびDataTableDispose()メソッドは、継承の副作用のためにのみ存在します。つまり、実際には、ファイナライズに役立つことは何もしません。

DataSetsDataViewsDataTablesは、コンストラクターのファイナライズを抑制していることがわかりました。これが、それらに対してDispose()を呼び出しても明示的に何もしない理由です。

おそらく、これは、前述のように、管理されていないリソースがないために発生します。そのため、MarshalByValueComponentが管理されていないリソースを考慮に入れているにもかかわらず、これらの特定の実装には必要がないため、ファイナライズを省略できます。

概要 この巨大な答え

間違いなく、DisposeはFinalizableオブジェクトで呼び出す必要があります。

DataTablesはファイナライズ可能です。

Disposeを呼び出すと、メモリの再利用が大幅に高速化されます。

MarshalByValueComponentGC.SuppressFinalize(this)Dispose()を呼び出します-これをスキップすると、メモリが再利用される前に、数百ではないにしても数十のGen0コレクションを待機する必要があります。

参考資料:

この質問 および関連する 回答 を参照してください。

20
MoonKnight

Dispose()メソッドはメモリを解放せず、オブジェクトをnullにしませんか?

Disposeであり、廃棄パターンは、管理対象メモリの再利用や管理対象オブジェクトの「削除」(実行できないこととガベージコレクタの目的の両方)ではなく、管理対象外のリソースの廃棄/解放を処理するためのものです。 SqlConnectionなど、リリース可能なアイテムを持つ他の管理対象リソース。それは確かに参照をnullしませんが、廃棄時から使用できなくなる可能性があります。

どうすればnullにするか、このオブジェクトが占めるメモリを解放できますか?

参照をnullにする場合は、単にdt = nullが機能しますが、これは機能しませんDataTableインスタンスがgrdView.DataSourceによって参照されるため、何らかの利点があります。 dtgrdView.DataSourceはどちらも、同じ基になるDataTableインスタンスへの参照になります。

また、これはメソッドの一部であると思われます。その場合、dtはとにかくメソッドスコープです。

このようなことについてあまり心配する必要はありません。 try-finally/SqlConnectionの外にusingがあることについてもっと心配します。そこで、接続を開いたままにしておくリスクがあります。

Disposeを実装するアイテムでIDisposableを呼び出すことを好む傾向があります。これは、veryの正当な理由であると考えています:これ公開契約です。それを呼び出すことが何かをするかどうかの事実は実装の詳細であり、変更される可能性がありますすぐに通知されます。


var dt = new Datatable();

using (var conn = new SqlConnection(""))
using (var comm = new SqlCommand("sp_getData", conn))
{
    conn.Open();

    using (var reader = comm.ExecuteReader())
    {
        dt.Load(reader);
    }
}

grdView.DataSource = dt;
8

Clear()関数を使用してみてください。それは私が処分するのに最適です。

DataTable dt = GetDataSchema();
//populate dt, do whatever...
dt.Clear();
2
Hasan Savran