【问题标题】:DataReader causing SQL Server to leak available memoryDataReader 导致 SQL Server 泄漏可用内存
【发布时间】:2015-04-30 01:32:59
【问题描述】:

我有一个 PowerShell 脚本,它从本地 SQL Server Express 2014 数据库读取数据并将其写入 CSV 文件。它运行良好,但几乎耗尽了 SQL Server 的整个可用内存池,并且在脚本完成运行时不会释放它。即使调用 GC.Collect() 也不会释放内存;我必须重新启动 SQL Server 服务才能恢复它。

这是脚本的相关部分,我已经确定发生了泄漏:

try {
    $sqlConn = New-Object -TypeName System.Data.SqlClient.SqlConnection($sqlConnString);
    $sqlConn.Open();

    $sqlCmd = New-Object -TypeName System.Data.SqlClient.SqlCommand;
    $sqlCmd.Connection = $sqlConn;
    $sqlCmd.CommandType = [System.Data.CommandType]::Text;
    $sqlCmd.CommandText = "SELECT * FROM $exportReadings";

    #Write contents to a CSV file
    $line = New-Object -TypeName System.Text.StringBuilder;
    $out = New-Object -TypeName System.IO.StreamWriter -ArgumentList $csvFile, $false;
    $out.WriteLine("HEADER_ROW");        
    $reader = $sqlCmd.ExecuteReader();
    $cols = $reader.VisibleFieldCount;
    while ($reader.Read()) {
        $line.Clear();
        for ($i = 0; $i -lt $cols; $i++) {
            $val = $reader.GetValue($i);
            if ($val -like "*$delimiter*") {
                $line.Append('"').Append($val).Append('"');
            }
            else {
                $line.Append($val);
            }

            if ($i -ne ($cols - 1)) {
                $line.Append($delimiter);
            }
        }
        $out.WriteLine($line.ToString());
    }
}
catch {
    throw;
}
finally {
    if ($reader) { $reader.Dispose(); }
    if ($out) {
        $out.Close();
        $out.Dispose();
    }
    $sqlCmd.Dispose();
    $sqlConn.Dispose();
}

如果我在运行脚本之前查询 SQL Server 上的内存使用情况(我正在使用 SELECT * FROM sys.dm_exec_query_resource_semaphores),我会得到大约 750K 的 `available_memory_kb)。之后,它大约是 150K,即使脚本已经终止。

我已尝试尽可能释放所有资源,但我一定遗漏了一些东西。有什么想法吗?

【问题讨论】:

    标签: sql-server powershell ado.net


    【解决方案1】:

    我认为这根本不是 powershell 问题。如果您看到 SQL Server 的内存增加了,那么这很正常。 SQL 服务器将使用它可以使用的所有内存进行缓存。如果系统中的其他东西需要它,该内存将被释放,但想法是,如果可能的话,它将把每个数据库都放入内存并将其留在那里,以便将来的访问非常快。

    A Sysadmin’s Guide to Microsoft SQL Server Memory

    【讨论】:

    • 对不起,我尽力把我的问题说清楚,但这并不是 SQL Server 正在使用的系统内存的增加。这是 SQL Server 内部可用内存的减少
    • 这只是一个观察结果还是导致了实际问题?您必须重新启动 SQL Server 服务这一事实支持了此问题出在 SQL Server 本身的想法。
    • 它引起了问题。一旦内存丢失,它就不会用于其他查询,这些查询只是锁定并无休止地旋转,因为服务器没有资源来完成它们。因此,这不是内存没有被回收的情况,因为它还没有被需要。
    猜你喜欢
    • 1970-01-01
    • 2014-04-19
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 2014-06-07
    • 2013-11-20
    • 2011-10-28
    相关资源
    最近更新 更多