none
I Dispose the DataTable Object then also OutOfMemoryException is occur RRS feed

  • Question

  • In Following Code I write Dispose to release the Memory of Datatable
    then Also OutOfMemoryException is occur. I want meaning full answer of My following Question

    Dim row As DataRow
    Dim Dt1 As New DataTable()
    Dt1.Columns.Add("C_A")
    Dt1.Columns.Add("C_B")
    Dt1.Columns.Add("C_C")
    
    For i As Integer = 1 To 9000000
    row = Dt1.NewRow()
    row.Item("C_A") = "data 1"
    row.Item("C_B") = "data 2"
    row.Item("C_C") = "data 3"
    Dt1.Rows.Add(row)
    Next
    Dt1.Dispose()
    Dt1 = Nothing

    After that I remove the Dt1.Dispose() method and Write Dt1.Clear
    then OutOfMemoryException is Not Occur

    Dim row As DataRow
    Dim Dt1 As New DataTable()
    Dt1.Columns.Add("C_A")
    Dt1.Columns.Add("C_B")
    Dt1.Columns.Add("C_C")
    
    For i As Integer = 1 To 9000000
    row = Dt1.NewRow()
    row.Item("C_A") = "data 1"
    row.Item("C_B") = "data 2"
    row.Item("C_C") = "data 3"
    Dt1.Rows.Add(row)
    Next
    Dt1.Clear()
    Dt1 = Nothing

    I Already Test All case (with Clear,dispose,and assign null) but I Have Bellow three question.

    1) only Dispose() Will not Release Memory Properly. ?
    2) I Have To Write Both Clear() and Dispose() to release Memory??
    3) and it is necessary to assign Nothing at last to DataTable OBJECT to release Memory Properly. ???



    Monday, November 5, 2018 8:16 AM

All replies

  • Hi,

    It is usually enough to set DataTable to null, and you can wait for the GC to recycle. If you want to use the Dispose() method, it is usually

     Using dt As DataTable = New DataTable
    
            End Using

    This will implicitly call the Dispose() method at the end of the curly braces, and dt becomes a local variable immediately out of scope, and there will be no call errors.

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, November 5, 2018 8:53 AM
  • https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/using-statement

    <copied>

    A Using block behaves like a Try...Finally construction in which the Try block uses the resources and the Finally block disposes of them. Because of this, the Using block guarantees disposal of the resources, no matter how you exit the block. This is true even in the case of an unhandled exception, except for a StackOverflowException.

    <end>

    Monday, November 5, 2018 9:59 AM
  • According to the sources, seems that DataTable does not clear the rows during Dispose: https://referencesource.microsoft.com/#System.Data/System/Data/DataTable.cs,8aab738ad2b51b53.

    Try the next approach too:

    Using dt1 As New DataTable
       AddHandler dt1.Disposed, Sub() dt1.Clear()
    
       . . .
    
    End Using




    • Edited by Viorel_MVP Tuesday, November 6, 2018 6:56 AM
    Tuesday, November 6, 2018 6:53 AM
  • The following is an exercise in seeing what it takes to release memory used by your code. It is not recommended to use GC.Collect.

    In regards to the Dispose method, it does nothing, it's there for inheritence only.

    Public Class Form1
        Private Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click
            Console.WriteLine($"Before using DataTable: {GC.GetTotalMemory(False)}")
            Using Dt1 As New DataTable
                AddHandler Dt1.Disposed, Sub() Dt1.Clear()
                Dim row As DataRow
    
                Dt1.Columns.Add("C_A")
                Dt1.Columns.Add("C_B")
                Dt1.Columns.Add("C_C")
                Console.WriteLine()
    
                For i As Integer = 1 To 9000000
                    row = Dt1.NewRow()
                    row.Item("C_A") = "data 1"
                    row.Item("C_B") = "data 2"
                    row.Item("C_C") = "data 3"
                    Dt1.Rows.Add(row)
                Next
            End Using
            Console.WriteLine($"After using DataTable: {GC.GetTotalMemory(False)}")
        End Sub
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            ' Not recommended but for this post this is the only way to reduce memorty
            ' used in button1 datatable code.
            GC.Collect()
            Console.WriteLine($"GC.Collect() in button2: {GC.GetTotalMemory(False)}")
        End Sub
    End Class
    

    Results

    Before using DataTable: 475436
    After using DataTable: 1304228640
    GC.Collect() in button2: 215732


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Tuesday, November 6, 2018 2:54 PM
    Moderator