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

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

 DPB18 июл. 2016 г., 04:18
Будет ли объект .NET, связанный с открытым соединением, по-прежнему собирать мусор после того, как он выходит из области видимости, даже если неуправляемый ресурс не был утилизирован должным образом?
 MickyD18 июл. 2016 г., 03:11
Если класс понимаетIDisposable тогда это хороший признак того, что вам нужноDispose() Это
 MickyD18 июл. 2016 г., 06:01
.NET объекты не сразу GC'd, когда они выходят из области видимости (если вы не используетеusing что не совсем то же самое). Это не похоже на c / c ++. До тех пор, пока это не произойдет, остается открытым дорогой неуправляемый ресурс, который может привести к исчерпанию соединений с базой данных.
 Ňɏssa Pøngjǣrdenlarp18 июл. 2016 г., 01:16
Они должны быть не просто закрыты, а утилизированы. Оберните их, используя блоки. Без них такие ресурсы, как дескрипторы и такие, которые они выделяют, не освобождаются; так что это, скорее всего, не будет причинойобъем памяти Утечки. Утилизируйте все, что имеетDispose метод. Вы также можете запустить CA в своем проекте, чтобы найти фактические утечки памяти

Ответы на вопрос(3)

Если все еще есть утечки памяти, то сообщите об ошибке в 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
Решение Вопроса

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

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

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

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

 Scott Hannen18 июл. 2016 г., 04:22
Возможно. Вероятно, самый простой способ определить это - закрыть / удалить соединения и посмотреть, исправит ли это.
 DPB18 июл. 2016 г., 04:16
Возможно ли, что описанная мной ситуацияпоявиться как утечка памяти для профилировщика? Это был кто-то еще в команде, кто профилировал приложение и обнаружил утечки; Я начал смотреть на код после факта и всего, кроме соединений SQL, похоже на нормальный управляемый код .NET.

как инструктировать базу данных для обновления «с помощью» и «попробовать поймать»

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 по умолчанию прекращается, если не происходит никаких действий.

 Todd Beaulieu28 сент. 2017 г., 16:41
В примере tcf вы забыли удалить экземпляры sqlconnection и sqlcommand в finally, так что это не полное решение или сравнение с использованием.
 user380052729 сент. 2017 г., 08:40
Правильно, хотя мне также интересно, так как эта функция является локальной переменной, она должна быть расположена при выходе из функции, как и любая другая переменная внутри функции. Ну да ладно, я думаю, именно поэтому все эти вещи больше нравятся людям.

Ваш ответ на вопрос