我创建了一个简单的数据获取方法,该方法可以从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()
[
答案 0 :(得分:4)
GC.Collect()强制立即进行所有世代的垃圾收集。因此,如果您稍等片刻,或者应用程序内存不足,GC将自动调用。 因此,我认为这似乎不是内存泄漏。
答案 1 :(得分:0)
这是问题
完成此方法后,我们仅取消引用DataTable对象,而不删除它。
还要检查GC.GetGeneration(dt),如果该对象升级到第1代或第2代(这将是性能问题)
但是我想,GC会完成它的工作,因为您的数据表上没有引用根,
所以GC只是扩大了第0代的大小,当下一代0 GC出现时,它将清除这些数据表。