Member 11936418 Ответов: 3

Sqldataadapter fill datatable вызывает утечку памяти


I have a very strange problem where when I Fetch data from SQL DB through DataAdapter the memory in the application pool increases around 250k-300k.

  private const string _getSPName = "xxxxxxxx";
    private readonly string _connectionString;//This is assigned in the constructor
    public void populate()
    {
        using (SqlConnection sqlCon = new System.Data.SqlClient.SqlConnection(_connectionString))
        {
            sqlCon.Open();
            if (sqlCon.State == ConnectionState.Open)
            {
                using (SqlCommand sqlCmd = new System.Data.SqlClient.SqlCommand(_getSPName, sqlCon) { CommandType = CommandType.StoredProcedure })
                {
                    SqlDataAdapter da = new SqlDataAdapter();
                    DataTable dt = new DataTable();
                    da.SelectCommand = sqlCmd;
                    sqlCmd.CommandTimeout = 300;
                    da.Fill(dt);

                }
            }
        }
    }


Что я уже пробовал:

I tried explicitly disposing the Adapter, DataTable and all the connection objects and also tried explicitely calling Garbage collector. But No Luck. 

3 Ответов

Рейтинг:
1

Maciej Los

В дополнение к OriginalGriff[^] это решение, я бы сказал, что использование использование инструкции - Справочник по C# | Microsoft Docs[^] обеспечивает способ быстро и легко утилизировать IDisposable объекты без участия программиста.

Итак, если объект DataTable[^] или объект DataAdapter[^] вызывает утечку памяти, вы можете использовать их между ними using{} утверждение, потому что оба объекта являются одноразовыми.
Например:

using (SqlCommand sqlCmd = new System.Data.SqlClient.SqlCommand(_getSPName, sqlCon) { CommandType = CommandType.StoredProcedure })
{
	sqlCmd.CommandTimeout = 300;
    using(SqlDataReader dr = sqlCmd.ExecuteReader())
	    using(DataTable dt = new DataTable())
		    dt.Load(dr);
}


Member 11936418

Я пробовал все это, но не помогло. Проблема в том, что когда я получаю данные из базы данных и заполняю их в datatable, память быстро увеличивается, и это не уменьшается.

Рейтинг:
0

OriginalGriff

Память не возвращается обратно в ОС, когда она закончена в вашем коде, если только ОС специально не попросит об этом - что она делает только тогда, когда она начинает работать на низком уровне.
Если вы используете кусок памяти, диспетчер памяти проверяет его свободный список, а если ему требуется дополнительный, он запрашивает его у операционной системы. Это остается частью приложения, даже когда вы выпустили его обратно в кучу и GC сделал свою работу.

Это нормально, и по замыслу: все остальное замедлило бы всю систему.


Maciej Los

5ed!

Рейтинг:
0

Dave Kreskowiak

Если вы смотрите в Диспетчере задач, чтобы увидеть, сколько памяти использует ваше приложение, оно лжет вам.

Он показывает вам, сколько памяти зарезервировано для вашего приложения, а не сколько оно на самом деле использует. Вы видите размер управляемой кучи, к которой ваше приложение имеет немедленный доступ.

Когда объекты выходят за пределы области видимости, сборщик мусора .NET освобождает объект и возвращает память обратно в управляемую кучу, а не в Windows.