Memory leak in .net application

2019-03-05 18:10发布

问题:

I am working on a desktop application in VB.net 2005. The application contains a timer with an interval of 1 min. Each time the timer ticks, a set of functions gets executed, mostly database related. Initially the application runs fine. In processes(Task manager) the cpu usage goes to 100% every time the timer is invoked. But the timespan is around 1 sec(negligible). However as the time passes and after around 20 hours the time span of timer_tick increases to something like 20-30 secs. In this period cpu usage is 100% and the application does not responds. Gradually the time span of timer_tick increases to 1 min and the cpu uses gets stuck to 100% and the application does not responds. All objects are properly disposed. Moreover, this issue is with pentium 4 processors. The application runs fine on core 2 duo.

The timer contains 4 functions... I am adding few of those functions..

 Public Sub SetNotes()
    Dim dtOld As DataTable
    Dim dtNew As DataTable
    Dim oApptTasks As New AppointmentsAndTasks

    dtOld = oApptTasks.PopulateAllTasks  ' get the source table
    dtNew = dtOld.Clone  '  make new table ad clone of old table

    If btnShowNotes.Text = "Hide Notes" Then
        For Each item As System.Data.DataRow In dtOld.Rows
            If Not IsDBNull(item("Notes")) Then
                If item("Notes") <> "" Then ' add only if not null and not blank
                    item("Task") = item("Task") & vbCrLf & item("Notes") ' concatenate the notes field
                End If
            End If
            dtNew.ImportRow(item) ' import modified row to new table
        Next

        grdcTask.DataSource = SetAssignedTo(dtNew) ' set the datasource
        grdcTask.DataSource = SetAssignedFrom(grdcTask.DataSource) ' set the datasource
        repMemoNotes.LinesCount = 0 ' adjust the height of custom field
    Else
        grdcTask.DataSource = SetAssignedTo(dtOld) ' set the datasource
        grdcTask.DataSource = SetAssignedFrom(grdcTask.DataSource) ' set the datasource
    End If
End Sub

Now this is one of the four functions called by timer...which uses the following code to fetch data from db.

  Using conn As New SqlConnection(glbSqlConnString)
        Try
            conn.Open()
            Dim dbDataAdapter As New SqlDataAdapter(oStrQueryBuilder.ToString, conn)
            dbDataAdapter.Fill(dbDataTable)

        Catch ex As Exception
            EventLog.WriteLog("App", ex.ToString, EventLogEntryType.Error)
        Finally
            If conn.State = ConnectionState.Open Then
                conn.Close()
            End If
        End Try
    End Using

Many Select, Update and delete queries are performed in the timer.

This problem occurs when I am using around 7000 records in database. With less records the problem does not occurs. So, can the SQL queries be the culprit for this.

Can you please suggest what could be the culprit in memory leak?

Looking forward for help. Thanks in advance.

回答1:

I would recommend using some Profiler Tools. There are some free but in my experience the comercial tools are worth the price.

For Example ANTS Profiler. http://www.red-gate.com/products/dotnet-development/ Perphaps the evaluation perios is enough for you ?



回答2:

I am making a guess here, since you have mentioned that the issue only occurs when the record count is more than 7000; it could be a situation where the next trigger of timer has fired before the previous event has completed its database operation. This could cause a backlog of operation that needs to be done, and it just keeps getting more when time goes on.

I would recommend you make sure only 1 set of operation is running at any given time. For example use the below logic to run the timer function

Function TimerFunction
     'Diable Timer - This will disable the timer so that no more timer events are triggered'
     timer1.Enabled = False


     Function1()
     Function2()
     Function3()
     Function4()

     'Enable Timer - Now enable the timer again so that it can continue normally'
     timer1.Enabled=True

End

But you would sure need to profile your database operation and tune the operation which is delaying the execution of the program. It is of concern that your applications performance starts lagging at just 7000 records.

Hope that helps.