简单地说,我的sqlservr.exe是内存泄漏每当我的服务使用它。所以问题是,在哪里,为什么!(
我将连接初始化为null。并且有一个最后条款来确保它们是关闭的……(我也试过在数据读取器上。dispose,但没有帮助)。
我花了一天多的时间试图找出问题所在。我只能说它就在这里的某个地方。
private Int32 GetCount(String From, String Where)
{
//Build SQL string from given parameters.
String sql = "SET dateformat DMY SELECT COUNT(*) as Count FROM " + From + " WHERE " + Where;
SqlDataReader dataCount = null;
SqlCommand sqlCommCount = null;
SqlConnection sqlConCount = null;
try
{
sqlCommCount = new SqlCommand();
sqlConCount = new SqlConnection();
sqlCommCount.Connection = sqlConCount;
sqlConCount.ConnectionString = "connectionstring";
sqlCommCount.CommandText = sql;
sqlConCount.Open();
dataCount = sqlCommCount.ExecuteReader();
while (dataCount.Read())
{
return Convert.ToInt32(dataCount["Count"]);
}
return 0;
}
finally
{
sqlConCount.Close();
sqlCommCount.Dispose();
if (dataCount != null)
dataCount.Close();
}
}
解决:
无泄漏
我讨厌Sqlserver不告诉我它缓存内存,而不是在使用连接时,所以只是增加和增加(直到需要)。
使用
用关键字重构你的代码内存占用是不确定的,在你的样本中,可执行文件使用的有效内存只有在垃圾收集发生时才会被释放,所以你可以看到内存增加,但这可能不是问题,它迟早会被收集,内存将返回到一个适当的值。
看到注释后,问题似乎不在你的c#代码中(如果使用using关键字,这也是一个好主意!),如果有问题…
SQL Server将增加内存占用,直到它有可用的内存,它被设计成这样工作。在您的示例中,每次传递一个新的where子句时,它都会缓存SQL语句,因此内存使用将增加,直到您有可用的内存。
在这种情况下,我建议你重构你的代码,至少使用SQL参数来创建where子句,这样SQL将始终保持不变,只有参数改变,这样SQL服务器将只缓存一条SQL语句,而不是数千条。更好的方法是创建一个存储过程,但通常有参数就足够了。
请记住,你构建SQL语句的方式是非常不安全的,可能会导致SQL注入攻击,使用参数也会解决这个问题。
对
马西莫
您的约定sqlConCount从未真正被处理过。
SqlConnection的Dispose实现在Dispose之前关闭连接。所以最好是使用using命令来连接,这样你就可以确保问题不会出现在那里。
但是当你不保存引用时,它应该被垃圾收集,所以不是真正的问题。你百分之百确定内存泄漏在这里吗?
看起来你在最后一个块有机会触发之前返回你的整数。尝试在Try块中分配它,并在finally块
后返回它int value = o;
try
{
...
value = Convert.ToInt32(dataCount["Count"]);
}
finally
{
//close connection
}
return value;
我认为string + string
导致泄漏,切换到StringBuilder。你也不处置SqlConCount
和dataCount
(你可以尝试重构你的代码使用using