私は非常に単純なコードを調べていて、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にするか、このオブジェクトが占有しているメモリを解放できますか?
DataSet
とDataTable
には実際には管理されていないリソースがないため、Dispose()
は実際にはあまり機能しません。 DataSet
およびDataTable
のDispose()
メソッドは、継承の副作用のためにのみ存在します。つまり、実際には、ファイナライズに役立つことは何もしません。
DataSets
、DataViews
、DataTables
は、コンストラクターのファイナライズを抑制していることがわかりました。これが、それらに対してDispose()
を呼び出しても明示的に何もしない理由です。
おそらく、これは、前述のように、管理されていないリソースがないために発生します。そのため、MarshalByValueComponent
が管理されていないリソースを考慮に入れているにもかかわらず、これらの特定の実装には必要がないため、ファイナライズを省略できます。
概要 この巨大な答え :
間違いなく、DisposeはFinalizableオブジェクトで呼び出す必要があります。
DataTablesはファイナライズ可能です。
Disposeを呼び出すと、メモリの再利用が大幅に高速化されます。
MarshalByValueComponent
はGC.SuppressFinalize(this)
でDispose()
を呼び出します-これをスキップすると、メモリが再利用される前に、数百ではないにしても数十のGen0
コレクションを待機する必要があります。
参考資料:
Dispose()メソッドはメモリを解放せず、オブジェクトをnullにしませんか?
Dispose
であり、廃棄パターンは、管理対象メモリの再利用や管理対象オブジェクトの「削除」(実行できないこととガベージコレクタの目的の両方)ではなく、管理対象外のリソースの廃棄/解放を処理するためのものです。 SqlConnection
など、リリース可能なアイテムを持つ他の管理対象リソース。それは確かに参照をnull
しませんが、廃棄時から使用できなくなる可能性があります。
どうすればnullにするか、このオブジェクトが占めるメモリを解放できますか?
参照をnullにする場合は、単にdt = null
が機能しますが、これは機能しませんDataTable
インスタンスがgrdView.DataSource
によって参照されるため、何らかの利点があります。 dt
とgrdView.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;
Clear()関数を使用してみてください。それは私が処分するのに最適です。
DataTable dt = GetDataSchema();
//populate dt, do whatever...
dt.Clear();