Утечка памяти в C # при извлечении данных из SQL Server - PullRequest
0 голосов
/ 09 октября 2019

Я создал простой метод извлечения данных, который извлекает данные из базы данных SQL Server.

Каждый раз, когда я извлекаю данные, вызывая этот метод, объем памяти увеличивается (память пула приложений). Когда я явно вызываю GC.Collect() после извлечения данных, память наполовину меньше, чем без GC.Collect().

Я знаю, что вызывать GC.Collect() - плохая практика, но без вызова я борюсь за уменьшение памяти.

private void DataPopulate(int ID)
{
    using (SqlConnection sqlCon = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings["SQL"].ConnectionString))
    {
        sqlCon.Open();

        if (sqlCon.State == ConnectionState.Open)
        {
            using (SqlCommand sqlCmd = new System.Data.SqlClient.SqlCommand("engine_connection_sendername_get", sqlCon) { CommandType = CommandType.StoredProcedure })
            {
                sqlCmd.Parameters.Add(new SqlParameter("id", ID));

                using (SqlDataAdapter da = new SqlDataAdapter())
                {
                    using (DataTable dt = new DataTable())
                    {
                        da.SelectCommand = sqlCmd;
                        sqlCmd.CommandTimeout = 300;
                        da.Fill(dt);
                    }
                }
            }
        }

        GC.Collect();
    }
}

Я использую описанный выше метод тестирования, чтобы просто проверить проблему с памятью,Я создал образец страницы .aspx, в которой есть только кнопка. Когда я нажимаю кнопку, этот метод вызывается. Datatable заполнен данными из базы данных SQL Server - и все.

И я проверяю память в пуле приложений. Ниже приведена сводка каждого нажатия кнопки и соответствующей памяти с использованием и без использования GC.Collect()

[MemoryUsage_AfterEachClick

Ответы [ 2 ]

4 голосов
/ 09 октября 2019

GC.Collect () вызывает немедленную сборку мусора для всех поколений. поэтому, если вы подождете некоторое время или когда приложению не хватит памяти, GC позвонит автоматически. Так что, на мой взгляд, это не утечка памяти.

0 голосов
/ 11 ноября 2019

Вот проблема,

Когда закончим этот метод, мы просто удаляем ссылку на объект DataTable, а не удаляем его.

А также проверяем GC.GetGeneration (dt), если этот объектповысить до поколения 1 или 2 (это будет проблема с производительностью)

Но я думаю, что GC справится со своей задачей, поскольку в вашей DataTable нет ссылочного корня,

, поэтому GC просто увеличитсяРазмер поколения 0, когда поступит следующее поколение GC, он очистит эти таблицы данных.

...