如果.NET SqlConnection对象未关闭会导致内存泄漏吗?

时间:2016-07-17 23:14:46

标签: .net memory-leaks ado.net sqlconnection

我知道您需要在.Close()对象上调用SqlConnection,以便在完成后将基础SQL连接释放回池中;但如果你不这样做,即使超出范围,.NET对象是否仍然留在内存中?我问,因为我正在使用一些遇到内存泄漏的代码,我注意到SqlConnection对象没有被关闭或处理(它们被创建,打开,然后只是被允许超出范围)。

3 个答案:

答案 0 :(得分:7)

问题不是内存泄漏。问题是与SQL服务器的连接仍然是打开的,这意味着连接不适用于需要与该服务器通信的其他内容。

如果连接超出范围并且被垃圾收集和处理,连接将最终关闭,但是不知道何时会发生这种情况。您的应用程序在给定时间只能打开这么多SQL连接,而SQL服务器本身只能支持这么多连接。

把它想象成一个负责任的人从图书馆借书。如果你没有归还这本书,它最终会回到图书馆,因为有一天你会死,当有人清理你的房子时,他们会找到这本书然后把它寄回图书馆。但如果每个人都这样做,那么在图书馆找书籍真的很难。因此,在我们准备好阅读之前,我们不会查看该书,我们会在完成后立即将其归还。

SQL连接也是如此。在您需要它们之前不要打开它们,并在完成它们后尽快关闭它们。并且,如其他答案所示,using通过确保连接将被处置(也关闭它)而不必使用try/finally来简化它。

答案 1 :(得分:0)

始终使用using(...)来配置sqlConn和sqlCmd。如果仍有内存泄漏, 那么错误报告给微软......如果你正确处理掉,那里就不会有内存泄漏

using (SqlConnection sqlConn = new SqlConnection(....))
{
  using (SqlCommand sqlCmd = new SqlCommand(....))
  {
    .... do something here with your sqlConn and sqlCmd
  }  // sqlCmd will be properly disposed here
}  // sqlConn will be properly disposed here

答案 2 :(得分:0)

如何指示数据库更新有2种首选方法 "使用"并且"尝试捕捉"

public void PerformStoredProcedure()
{
    string cs = System.Configuration.ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString; // reading by name DBCS out of the web.config file
    using (SqlConnection connection = new SqlConnection(cs))
    {
        SqlCommand cmd = new SqlCommand("spDoMyStoredProcudere", connection);
        cmd.CommandType = System.Data.CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@good", TextBox1.Text + "%"); // input for stored procedure
        connection.Open();

        //--
        GridView1.DataSource = cmd.EndExecuteReader();
        GridView1.DataBind();
    }
} 

使用的好处是它会自动关闭。

另一个方法是尝试捕捉建筑

protected void Page_Load(object sender, EventArgs e)
{
    string cs; // conection string.
    cs = "data source=.; "; //servername (.) = local database password. 
 // cs = cs + "user id=sa; password=xxxxx"; using sql passwords authentication.
    cs = cs + "integrated security=SSPI"; // using windows nt authentication.

    //its better to store connnection in web.config files. so all form pages can use it.

    cs = System.Configuration.ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString; // reading by name DBCS out of the web.config file

    SqlConnection con = new SqlConnection(cs);
    try
    {  // if any problem ocures we still close the connection in finally.
        //SqlCommand cmd = new SqlCommand("Select * from tblSample", con);  //execture this command on this coneection on this table


        SqlCommand cmd = new SqlCommand("Select title, good from tblSample",con);
        con.Open(); 

        GridView1.DataSource = cmd.ExecuteReader(); //execure reader T_SQL statement that returns more then 1 value
        //cmd.ExecuteNonQuery  //for insert or update or delete
        //cmd.ExecuteScalar //for single value return
        GridView1.DataBind();
    }
    catch
    {
        Response.Write("uh oh we got an error");
    }
    finally
    {
        con.Close();
    }

尽管使用主要用于异国情调,但抓取选项也可能很好,但它需要更多输入。

如果我在20分钟左右后正确提醒,默认情况下IIS会话将在没有操作的情况下终止。