Может ли объект .NET SqlConnection вызвать утечку памяти, если он не закрыт?

.net memory-leaks ado.net sqlconnection

2331 просмотра

3 ответа

13 Репутация автора

Я понимаю , что вам нужно вызвать .Close()на SqlConnectionобъект , чтобы освободить базовое соединение SQL обратно в пул , когда вы сделали с ним; но если вы воздерживаетесь от этого, остается ли объект .NET в памяти даже после выхода из области видимости? Я спрашиваю, потому что я работаю с некоторым кодом, который испытывает утечки памяти, и я заметил, что SqlConnectionобъекты не закрываются и не удаляются (они создаются, открываются, а затем просто выходят из области видимости).

Автор: DPB Источник Размещён: 17.07.2016 11:14

Ответы (3)


0 плюса

0 Репутация автора

Всегда используйте использование (...) для удаления sqlConn и sqlCmd. Если все еще есть утечки памяти, то сообщите об ошибке в Microsoft ... Если вы правильно утилизируете, утечки памяти там не должно быть

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
Автор: user6522773 Размещён: 17.07.2016 11:21

7 плюса

17808 Репутация автора

Решение

Проблема не в утечке памяти. Проблема заключается в том, что соединение с сервером SQL остается открытым, а это означает, что соединение недоступно для чего-то другого, что необходимо для связи с этим сервером.

Соединение в конечном итоге будет закрыто, если оно выйдет за пределы области и соберет и утилизирует мусор, но пока неизвестно, когда это произойдет. Ваше приложение может иметь только столько соединений SQL, открытых в данный момент времени, а сам сервер SQL может поддерживать только столько соединений.

Думайте об этом как о ответственном человеке, заимствующем книгу из библиотеки. Если вы не вернете книгу, она в конечном итоге вернется в библиотеку, потому что однажды вы умрете, и когда кто-то уберет ваш дом, они найдут книгу и отправят ее обратно в библиотеку. Но если бы все так делали, было бы очень трудно найти книги в библиотеке. Таким образом, мы не проверяем книгу, пока мы фактически не готовы прочитать ее, и мы возвращаем ее, как только закончим.

То же самое с соединениями SQL. Не открывайте их, пока они вам не понадобятся, и закройте их как можно скорее, когда закончите с ними. И, как показано в других ответах, usingупрощает его, гарантируя, что соединение будет удалено (что также закрывает его) без использования try/finally.

Автор: Scott Hannen Размещён: 18.07.2016 02:03

0 плюса

971 Репутация автора

Есть 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();
    }

Хотя использование в основном используется для экзотического сценария, опция catch тоже может быть полезной, но требует большего набора текста.

И если я правильно напомню, через 20 минут или около того сеанс IIS по умолчанию прекращается, если не происходит никаких действий.

Автор: user3800527 Размещён: 15.10.2016 12:08
Вопросы из категории :
32x32