Куда девается память в .NET C#?

Глупый, наверное, со стороны вопрос... но с таким столкнулся впервые, при исследовании работоспособности C# программы в Process Explorer потихоньку утекает память.

Запуск пациента происходит под отладчиком Visual Studio, как можно определить, куда и на что девается память и почему не может освободиться?
  • Вопрос задан
  • 3359 просмотров
Пригласить эксперта
Ответы на вопрос 3
@plasticmirror
доттрейс.мемори?

п.с. что такое - утекает? GC.Collect() освобождает "лишнее" или нет? вызовы всякого unmanaged кода или процессов - есть?
Ответ написан
Комментировать
askeet
@askeet Автор вопроса
Счетчик GS Handles постоянно меняется и растет 500 - 600 , 522 - 700 , 600 - 839 , 993 - 1100.
На форме при обновлении DataTableGrid используется Dictionary < string,string > через DataSource.
Ответ написан
Комментировать
askeet
@askeet Автор вопроса
После изучения проблемы выявлено следующее при записи через ODBC Manager данных в базу данных имеются большие до 30 Мегабайт скачки в памяти, которые в последствии очищаются медленней планируемого обращения к базе данных. Итого 30 Мегабайт довольно быстро превращается в 400. Но после прекращения обращения к базе данных вся память постепенно очищается.
Функция записи в базу данных имеет следующий вид , к которой есть частое обращение
public static int ExecuteNonQuery(string query)
        {
            int ret = 0;
          //  return ret;  если раскоментировать  употребление памяти не увеличивается
            lock (Lock)
            {
                try
                {
                    using (OdbcConnection Connection = new OdbcConnection(ConnectionString))
                    {
                        Connection.Open();
                        if (Connection.State == System.Data.ConnectionState.Open)
                        {
                            using (var command = new OdbcCommand(query, Connection))
                            {
                                ret = command.ExecuteNonQuery();
                            }
                        }
                        Connection.Close();
                        //OdbcConnection.ReleaseObjectPool();
                    }
                    OdbcConnection.ReleaseObjectPool();
                }
                catch (Exception e)
                {
                    Console.WriteLine("ExecuteNonQuery=" + e.Message);
                }
            }
            return ret;
        }


При этом запись в базу осуществляется асинхронно

public static void AddRecordsInArhiveAsync(ushort Code, bool NewData, DateTime Now, bool Finish = false)
        {
                Thread _trdAddRecords = new Thread(      
                    delegate()      
                    {
                        lock (LockThis)                        
                            AddRecordsInArhive(Code, NewData, Now, Finish); // Внутри вызывается функция ExecuteNonQuery(string query)              
                    }
                );

                _trdAddRecords.Priority = ThreadPriority.Normal;
                _trdAddRecords.Start();
        }


Тогда была предпринята попытка перезаписи функции с асинхронного вызова AddRecordsInArhiveAsync на синхронный.

public static void AddRecordsInArhiveSync(ushort Code, bool NewData, DateTime Now, bool Finish = false)
        {
            lock (LockThis)
                AddRecordsInArhive(Code, NewData, Now, Finish);
        }


После этого сборщик мусора стал работать корректно.

Вопрос, что не так в функции AddRecordsInArhiveAsync ?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы