SQL Server数据提取时发生C#内存泄漏

时间:2019-10-09 04:33:37

标签: c# sql-server memory-leaks ado.net dispose

我创建了一个简单的数据获取方法,该方法可以从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 个答案:

答案 0 :(得分:4)

GC.Collect()强制立即进行所有世代的垃圾收集。因此,如果您稍等片刻,或者应用程序内存不足,GC将自动调用。 因此,我认为这似乎不是内存泄漏。

答案 1 :(得分:0)

这是问题

完成此方法后,我们仅取消引用DataTable对象,而不删除它。

还要检查GC.GetGeneration(dt),如果该对象升级到第1代或第2代(这将是性能问题)

但是我想,GC会完成它的工作,因为您的数据表上没有引用根,

所以GC只是扩大了第0代的大小,当下一代0 GC出现时,它将清除这些数据表。