Memory leak using .NET SqlConnection and DataSet

I have a memory leak problem in a utility program that runs SQL scripts and uploads the results to files. After executing queries that produce many rows of results, the memory usage in the process increases by 50 + MB each time and does not decrease.

Here is the code that opens the connection and retrieves the results:

using (var conn = new SqlConnection(DataSourceInfo.ConnectionString))
{
    conn.Open();

    var scmd = new SqlCommand(query_string, conn);
    scmd.CommandTimeout = 86400;

    var writer = dest.GetStream(); //the writer is disposed of elsewhere

    using (var da = new SqlDataAdapter(scmd))
    using (var ds = new DataSet())
    {
        da.Fill(ds);
        var table = ds.Tables[0];
        var rows = table.Rows;

        if (TaskInfo.IncludeColNames.Value)
        {
            object[] cols = new object[table.Columns.Count];

            for(int i = 0; i < table.Columns.Count; i++)
                cols[i] = table.Columns[i];

            LineFormatter(writer, TaskInfo.FieldDelimiter, null, false, cols);
            writer.WriteLine();
        }

        foreach(System.Data.DataRow r in rows)
        {
            var fields = r.ItemArray;

            LineFormatter(writer, TaskInfo.FieldDelimiter, TaskInfo.TextQualifier, TaskInfo.TrimFields.Value, fields);
            writer.WriteLine();
        }
    }
}

I used WinDbg with sos.dll to list the top objects by type after completion, and the process had a lot of time for the GC:

79333470      101       166476 System.Byte[]
65245dcc      177      3897420 System.Data.RBTree`1+Node[[System.Data.DataRow, System.Data]][]
0015e680     5560      3968936      Free
79332b9c      342      3997304 System.Int32[]
6524508c   120349      7702336 System.Data.DataRow
793041d0      984     22171736 System.Object[]
7993bec4       70     63341660 System.Decimal[]
79330a00  2203630     74522604 System.String

The second column is the number of objects, and the third is the total size.

There should not be any System.Data.DataRow objects. It seems that they somehow leaked, but I'm not sure how to do it.

What am I doing wrong?

: SqlDataReader , ( ), DataSet SqlDatReader . .

+3
4

LineFormatter -, , .

, . AFAIK, , . , GC.Collect() , , GC.Collect() - .

, , , .NET. PerfMon, , .

+2

DataRow !gcroot, , . . ( GC).

+2

- , , Nant .Net Memory Profiler. , 15- , , , , .

.Net Memory Profiler. , , AppDomain . , ; ( ), , emory, . , , , . !

0
source

You may need to put your SqlCommand in a use block or delete it manually.

0
source

Source: https://habr.com/ru/post/1758096/


All Articles