Может ли DataTable как параметр и возвращаемое значение вызвать утечку памяти? - PullRequest
1 голос
/ 29 марта 2020

Как следует из названия, мне было интересно, если использование DataTable (или любого типа объекта) в качестве параметра или возвращаемого значения вызывает утечки памяти? Предположим, у меня есть 3 разные функции:

public DataTable InitDT()
{
    //Create and Initializes the dataTable columns, and returns a DataTable
    DataTable dt = new DataTable();
    DataColumn column = new DataColumn();
    column.ColumnName = "Id";
    dt.Columns.Add(column);
    return dt;
}

public DataTable PopulateDT()
{
    //Populate an Initialized DataTable and return it
    DataTable dt = InitDT();
    DataRow row;
    row = dt.NewRow();
    dt.Rows.Add(row);
    return dt;
}

public void ReadDT()
{
    //Read return DataTable
    DataTable dt = PopulateDT();
    foreach (DataRow r in dt.Rows)
    {
        txtId.text = r[0].ToString();
    }
    dt.Dispose();
}

В моем коде только последняя функция вызывает dt.Dispose();, поэтому мне было интересно, что происходит с 2 ранее созданными таблицами DataTable. Сборщик мусора уже очищает их?

Ответы [ 2 ]

1 голос
/ 29 марта 2020

Не будет никакой утечки памяти, поскольку ADO. NET объекты не используют неуправляемые ресурсы .

Метод Dispose DataTable наследуется от MarshalByValueComponent , который к DataTable ничего не делает.

0 голосов
/ 29 марта 2020

1) Строго говоря, вы не можете получить утечку памяти в C#.

Это требует некоторого объяснения:

Во-первых, предполагается, что вы имеете дело исключительно с управляемым кодом. Если вы C# подключаетесь к любому неуправляемому коду, то вы можете получить утечки памяти там, но не в самом C#. Здесь нет неуправляемого кода.

Во-вторых, программа C# может, конечно, освободить меньше памяти, чем должна, но, строго говоря, это не утечка памяти. Утечка памяти происходит, когда программа теряет все ссылки на память, но память все еще выделяется. Это не может произойти в C#. Может случиться так, что вы случайно держите ссылки, которые вам не нужны (например, заполняете ссылки в List и не убираете те, с которыми вы закончили). Опять же, это не происходит здесь.

В-третьих, целью Dispose является не очистка памяти, а очистка ресурсов , отличных от памяти, например, файловых дескрипторов, соединений с БД и неуправляемых ресурсов (см. Выше).

Таким образом, пропуская Dispose, вы можете иметь утечку ресурса, но не утечку памяти.

2) Будет ли получена утечка ресурса, зависит от контекста

ReadDT является автономным - он создает (косвенно) и располагает DataTable и ничего не возвращает. Единственная проблема в том, что он должен иметь блок using для вызова Dispose, чтобы гарантировать его вызов при возникновении исключений.

Два других метода оба создают (прямо или косвенно) a DataTable и верни это. Они правильно не Dispose это делают, потому что если бы они это сделали, они бы возвращали удаленный объект, который не должен использоваться кем-либо.

Общее правило таково, если метод создает и возвращает одноразовый объект. объект, предполагается, что вызывающая сторона несет ответственность за ее удаление (как это сделано в ReadDT) или за перенос ответственности на что-то другое, обычно путем возврата объекта, как это делается двумя другими методами.

...