2

I am trying to figure out the best way to use a DataSet/DataTable and cleaning up properly afterwards.

I am a little puzzled as to what causes memory to be released. I tested my theory with a test application where I populated the same DataTable multiple times in a loop and looking at Windows' Task Manager for the memory footprint after 3 forced GC collects.

What I found is that:

  1. If I did not call Clear or Dispose, or set the DataTable variable to Nothing, the final memory consumption in Task Manager was about 30k.

  2. If I just set the variable to Nothing inside the loop, the final memory was about 15k.
    Question: Why does setting the variable to Nothing make a difference?

  3. If I called only the Dispose method inside the loop, the final memory was about 19k.

  4. If I called only Clear inside the loop, the final memory was about 16.5k. In fact, it did not change even after the GC.Collect.

I would really appreciate if someone can share what is the best way to use and cleanup DataSets when no longer needed.

Sample code is shown below.

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

Edit: I am looking for best practices for managing memory of DataSets and/or DataTables that are passed around, where the creating method is not necessarily tasked with cleaning up the memory. Also, why does setting an object/variable to Nothing within a function performs differently than just letting it go out of scope.

4

3 回答 3

5

“清理”数据的最佳方法是切换到任何实现1的Using语句一旦你实现了这个模式,你就会对你设计的数据结构有最合理的内存使用。IDisposable

Using oConn As New SqlConnection("Server=Myserv;Database=myDB;UserId=myuserid;Password=mypassword;")
    oConn.Open()
    Using oCommand As New SqlCommand("Select  * from Users", oConn)
        ' other code as needed, wrap IDisposable in Using...EndUsing
    End Using
End Using

这并不能保证您的数据结构本身将具有内存效率,只是它们将仅在必要时保留资源。

1. 是的,你有时不能使用一个,但如果你不使用 using 语句是错误的前提下工作,你会更好。

于 2013-04-01T21:07:30.227 回答
0

使用任何必须在使用后释放的资源(包括 DataTable 或 Dataset)的最佳方式是尽可能使用关键字 Using。如果无法使用 Using 关键字,您应该执行与 Using 关键字等效的操作,例如:try { } Catch(Exception ex) { } finally { object.dispose() }

根据 msdn,任何实现 IDisposable 的对象都应该使用 dispose 方法释放资源。由于 Dataset 和 DataTable 都继承自实现 IDisposable 的 MarshalByValueComponent,因此最好调用 dispose 方法。如果有任何资源没有实现 IDisposable 方法,那么您可以实现 IDisposable 接口并覆盖 dispose 方法并在 dispose 方法中进行资源清理。通过将 DataSet 或 DataTable 设置为 null,您只需删除最终将由 Garbage Collector 收集的引用。但是使用 dispose 方法是更好的方法。您不必显式调用 GC.Collect 方法,因为垃圾收集器通常在后台运行,并且每当内存低于某个阈值(由编译器确定)时,它将释放这些资源使用的内存。http://msdn.microsoft.com/en-us/library/0xy59wtx(v=vs.110).aspx )

于 2014-03-13T02:30:16.107 回答
0

"And why does setting somthing to nothing within a function perform differently than just letting it go out of scope?"

You have accessed the somthing, so it is not eligible for GC before then.

When GC occurs is a bit non-deterministic: apparently it schedules its next invocation depending on several factors (cite: http://channel9.msdn.com/Shows/Defrag-Tools/Defrag-Tools-33-CLR-GC-Part-1 (a video)).

于 2013-04-02T20:37:09.050 回答