Утечка памяти в приложении .net

#.net #sql-server #vb.net #sql-server-2008 #timer

#.net #sql-сервер #vb.net #sql-server-2008 #таймер

Вопрос:

Я работаю над настольным приложением в VB.net 2005 год. Приложение содержит таймер с интервалом в 1 минуту. Каждый раз, когда таймер отсчитывает время, выполняется набор функций, в основном связанных с базой данных. Изначально приложение работает нормально. В процессах (диспетчер задач) загрузка ЦП достигает 100% при каждом вызове таймера. Но временной интервал составляет около 1 секунды (незначительный). Однако по прошествии времени и примерно через 20 часов промежуток времени timer_tick увеличивается примерно до 20-30 секунд. В этот период загрузка процессора составляет 100%, и приложение не отвечает. Постепенно промежуток времени timer_tick увеличивается до 1 минуты, а загрузка процессора застревает на 100%, и приложение не отвечает. Все объекты расположены правильно. Более того, эта проблема связана с процессорами pentium 4. Приложение отлично работает на core 2 duo.

Таймер содержит 4 функции… Я добавляю несколько из этих функций..

  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") amp; vbCrLf amp; 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
  

Теперь это одна из четырех функций, вызываемых таймером…который использует следующий код для извлечения данных из базы данных.

   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
  

Многие запросы Select, Update и delete выполняются по таймеру.

Эта проблема возникает, когда я использую около 7000 записей в базе данных. При меньшем количестве записей проблема не возникает. Итак, могут ли SQL-запросы быть причиной этого.

Не могли бы вы подсказать, что может быть причиной утечки памяти?

С нетерпением жду помощи. Заранее спасибо.

Комментарии:

1. Посмотрите на счетчики производительности, особенно с точки зрения сборки мусора. Вы профилировали свой код, чтобы узнать, куда идет процессор?

2. Можем ли мы увидеть что-то помимо теории??? что-то происходит, но, не видя, трудно понять, что именно…

3. Я не использовал профилировщик. Но заметили, что код внутри таймера, который содержит несколько взаимодействий с sql server, создает проблему. Я отключил таймер, и проблема исчезла.

4. Используете ли вы неуправляемые ресурсы? Вы уверены, что все утилизируется правильно? Пожалуйста, опубликуйте код, который выполняется в событии Tick.

5. @GeekOnDemand Публикует код, облегчающий помощь вам.

Ответ №1:

Я бы рекомендовал использовать некоторые инструменты профилировщика. Есть несколько бесплатных, но, по моему опыту, коммерческие инструменты стоят того.

Например, ANTS Profiler. http://www.red-gate.com/products/dotnet-development / Может быть, вам достаточно оценки perios?

Ответ №2:

Здесь я делаю предположение, поскольку вы упомянули, что проблема возникает только тогда, когда количество записей превышает 7000; это может быть ситуация, когда следующий триггер таймера сработал до того, как предыдущее событие завершило свою работу с базой данных. Это может привести к отставанию в выполнении операций, которые необходимо выполнить, и со временем их становится все больше.

Я бы рекомендовал вам убедиться, что в любой момент времени выполняется только 1 набор операций. Например, используйте приведенную ниже логику для запуска функции таймера

 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
  

Но вам обязательно нужно будет профилировать работу вашей базы данных и настроить операцию, которая задерживает выполнение программы. Вызывает беспокойство то, что производительность ваших приложений начинает отставать всего от 7000 записей.

Надеюсь, это поможет.