2

DataSet/を使用し、DataTable後で適切にクリーンアップする最良の方法を見つけようとしています。

メモリが解放される原因については、少し困惑しています。DataTableループ内で同じものを複数回入力するテスト アプリケーションで理論をテストし、 3 回の強制 GC 収集後のメモリ フットプリントについて Windows のタスク マネージャーを調べました。

私が見つけたのは次のとおりです。

  1. Clearまたはを呼び出さなかった場合、または変数をにDispose設定しなかった場合、タスク マネージャーでの最終的なメモリ消費量は約 30k でした。DataTableNothing

  2. 変数をNothingループ内に設定した場合、最終的なメモリは約 15k でした。
    質問: 変数を設定するNothingと違いが生じるのはなぜですか?

  3. Disposeループ内のメソッドだけを呼び出した場合、最終的なメモリは約 19k でした。

  4. ループ内でのみ呼び出した場合Clear、最終的なメモリは約 16.5k でした。実際、その後も変わりませんでしたGC.Collect

DataSet不要になったときに sを使用してクリーンアップするための最良の方法を誰かが共有できれば、本当に感謝しています。

サンプルコードを以下に示します。

Imports System.Data.SqlClient;
Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Test()

        GC.Collect()
        GC.Collect()
        GC.Collect() 'Throw in one more 
    End Sub


    Private Sub Test()
        Dim oDA As SqlDataAdapter = Nothing
        Dim oConn As SqlConnection = Nothing
        Dim oCommand As SqlCommand = Nothing
        Dim ods As DataSet = Nothing
        Dim oDt As DataTable = Nothing
        Try
            oConn = New SqlConnection("Server=Myserv;Database=myDB;UserId=myuserid;Password=mypassword;")
            oCommand = New SqlCommand("Select  * from Users", oConn)
            oConn.Open()
            ods = New DataSet

            oDA = New SqlDataAdapter(oCommand)

            For i As Integer = 0 To 50
                oDA.Fill(ods)
                oDt = ods.Tables(0)
                'oDt.Clear()
                'oDt.Dispose()
                oDt = Nothing
            Next
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
        Finally
            ods.Clear()
            ods = Nothing
            oConn.Close()
            oDA = Nothing
        End Try
    End Sub
End Class

DataSet編集: s および/またはs のメモリを管理するためのベスト プラクティスを探していますDataTable。ここでは、作成メソッドが必ずしもメモリのクリーンアップを担当しているわけではありません。Nothingまた、オブジェクト/変数を関数内に設定するのは、スコープ外に出すだけとは異なるのはなぜですか。

4

3 に答える 3

0

「そして、関数内で何かを何も設定しないことは、単にスコープ外に出すこととは異なる動作をするのはなぜですか?」

何かにアクセスしたため、それ以前は GC の対象になりません。

GC が発生するタイミングは少し非決定論的です。明らかに、いくつかの要因に応じて次の呼び出しをスケジュールします (引用: http://channel9.msdn.com/Shows/Defrag-Tools/Defrag-Tools-33-CLR-GC-Part -1 (ビデオ))。

于 2013-04-02T20:37:09.050 に答える
0

DataTable や Dataset など、使用後に解放する必要があるリソースを使用する最善の方法は、可能な限り Using キーワードを使用することです。Using キーワードを使用できない場合は、次のような Using キーワードと同等のことを行う必要があります。

msdn によると、IDisposable を実装するオブジェクトは、dispose メソッドを使用してリソースを解放する必要があります。Dataset と DataTable は、IDisposable を実装する MarshalByValueComponent を継承しているため、dispose メソッドを呼び出すことをお勧めします。IDisposable メソッドを実装していないリソースがある場合は、IDisposable インターフェイスを実装し、dispose メソッドをオーバーライドして、dispose メソッドでリソースのクリーニングを行うことができます。DataSet または DataTable を null に設定すると、ガベージ コレクターによって最終的に収集される参照が単純に削除されます。ただし、dispose メソッドを使用する方が優れたアプローチです。GC.Collect メソッドを明示的に呼び出す必要はありません。ガベージ コレクターは通常バックグラウンドで実行されており、メモリが特定のしきい値 (コンパイラによって決定される) を下回ると、それらのリソースによって使用されているメモリが解放されるためです。http://msdn.microsoft.com/en-us/library/0xy59wtx(v=vs.110).aspx )

于 2014-03-13T02:30:16.107 に答える