SQL 스크립트를 실행하고 결과를 파일로 덤프하는 서비스 프로그램에서 메모리 누수 문제가 있습니다. 많은 결과 행을 생성하는 쿼리를 실행 한 후에는 프로세스의 메모리 사용량이 매회 50MB 이상 올라가고 내려 가지 않습니다. 여기 .NET SqlConnection 및 DataSet을 사용한 메모리 누수
연결을 열고 결과를 검색하는 코드 :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가 실행을 완료 한 후에 유형별 가기 객체를 나열 sos.dll와 WinDbg를 사용하고, 처리가 많은 시간이 있었다 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
두 번째 열은 개체 수이고 세 번째 열은 전체 크기입니다.
뛰어난 System.Data.DataRow 개체가 없어야합니다. 그들이 어떻게 든 유출 된 것처럼 보이지만 어떻게 확신 할 수는 없습니다.
내가 뭘 잘못하고 있니?
참고 : 이전 버전에서는 행 데이터를 검색하기 위해 SqlDataReader를 사용했지만 그 방법은 열 머리글 (알고있는 것)을 얻지 못하고 DataSet과 SqlDatReader간에 데이터 집합을 공유하는 방식이 일부 쿼리에서 자동으로 실패합니다 . 메모리 누수 문제가있는 버전은 기억이 안납니다.
이상하게 보입니다. 그냥 펀트,'using' 문에서'SqlCommand'를 래핑 해 보았습니까? – kbrimington
GC.Collect()를 직접 호출하여 DataRow를 처음부터 수집 할 수 있는지 확인해 봤습니까? IIRC를 사용하면 메모리가 부족할 때까지 GC가 수집되지 않습니다. – Amy
어떤 이유로 저는 SqlCommand가 일회용이 아니라고 생각했습니다.나는 using 절에 넣을 것이지만,이 문제는 쿼리 크기에 비례하는 것으로 보인다. 나는 GC가 실제로 일어나지 않는다는 제안이 옳을 수도 있다고 생각한다. 내가 기회를 얻 자마자 확인해 볼게. –