我有一个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
),我的“available_memory_kb”大约为750K。之后,即使脚本终止,它也会在150K左右。
我试图尽可能释放每一种资源,但我必须遗漏一些东西。有什么想法吗?
答案 0 :(得分:1)
我根本不认为这是一个PowerShell问题。如果您发现SQL服务器的内存已经增加,那么这是正常的。 SQL Server将使用它可以使用的所有内存进行缓存。如果系统中的其他东西需要它,那么该内存将被释放,但是想法是,如果可能的话,它会将每个数据库带入内存并留在那里,以便将来访问非常快。