开发者

Memory leak in VB file reader

开发者_Python百科

I'm currently coding a file reader for fixed-width tables in VB, and the compiled application seems to be sucking down memory like there's no tomorrow. I'm working with a series of ~50 megabyte files, but after running through several, the process starts taking up about 200+ megabytes of RAM, which is way more than it should.

I've done some poking around, and I think the issue is the call to NewRow(), but don't take my word for it.

Does anyone have some tips for optimizing this? If the problem's with the NewRow() call, is there a way of clearing this out?

Code follows below:

Function LoadFixedWidthFileToDataTable(ByVal filepath As String, ByRef Colnames() As String, ByRef colwidth() As Integer) As DataTable

    Dim filetable As New DataTable
    For Each name As String In Colnames
        filetable.Columns.Add(name)
    Next

    Dim loadedfile As StreamReader
    Try
        loadedfile = New StreamReader(filepath)
    Catch io As IOException
        MsgBox(io.Message)

        Return Nothing
        Exit Function
    End Try

    Dim line As String = loadedfile.ReadLine
    Dim filerow As DataRow = filetable.NewRow
    Dim i As Integer = 0

    While Not loadedfile.EndOfStream
        line = loadedfile.ReadLine
        filerow = filetable.NewRow
        i = 0


        For Each colsize As Integer In colwidth
            Try
                filerow(i) = line.Substring(0, colsize)
                line = line.Remove(0, colsize)
            Catch ex As ArgumentOutOfRangeException ''If the line doesn't match array params
                Exit For
            End Try
            i = i + 1
        Next
        filetable.Rows.Add(filerow)
    End While

    loadedfile.Close()
    Return filetable
End Function


Mikurski,

I see one problem right off the bat. You are Dim'ing the Stream reader. You should enclose this in a using block, or be sure you do a .Dispose at the end of every code path. Anything that implements IDisposable interface should be disposed or used in a using block as follows:

    Using fs As New FileStream("C:\testing.txt", FileMode.Open)
        Using sr As StreamReader = New StreamReader(fs)
            Dim message As String = sr.ReadLine()
            MessageBox.Show(message)
        End Using
    End Using

I hope this helps,

Thanks!

EDIT:

Here are the items that implement IDisposable that your code isn't disposing:

  • DataTable
  • StreamReader

Hope this helps,

Thanks again!

Here is a function that is less memory intensive:

Function LoadFixedWidthFileToDataTable(ByVal filepath As String, ByRef Colnames() As String, ByRef colwidth() As Integer) As DataTable
    Dim filetable As New DataTable
    Try
        For Each name As String In Colnames
            filetable.Columns.Add(name)
        Next

        Try
            Using loadedfile As StreamReader = New StreamReader(filepath)
                Dim line As String = loadedfile.ReadLine
                Dim filerow As DataRow = filetable.NewRow
                Dim i As Integer = 0

                While Not loadedfile.EndOfStream
                    line = loadedfile.ReadLine
                    filerow = filetable.NewRow
                    i = 0

                    For Each colsize As Integer In colwidth
                        Try
                            filerow(i) = line.Substring(0, colsize)
                            line = line.Remove(0, colsize)
                        Catch ex As ArgumentOutOfRangeException
                            Exit For
                        End Try
                        i = i + 1
                    Next

                    filetable.Rows.Add(filerow)
                End While

                loadedfile.Close()

            End Using
        Catch io As IOException
            MsgBox(io.Message)

            Return Nothing
        End Try
        Return filetable
    Catch ex As Exception
        filetable.Dispose()
    End Try

    Return Nothing
End Function

I notice that you're returning the thing that you should be disposing. If you're doing this, you cannot dispose of it here. Instead, the place this function is called from must dispose of it. If you wrap a using block around this you will have issues as the returned object will be disposed before you have a chance to act upon it from the calling code.

Hope this helps,

Thanks again!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜