2014-11-05 4 views
4

현재 거대한 배치 프로그램의 메모리 사용을 최적화하고 있습니다. 대부분의 메모리는 다른 DataTable에서 사용됩니다. 내 DataTable dtTest는 약 260MB를 사용하고 있습니다.C# 최적화 메모리 사용 : DataTable에 의해 청구 된 메모리를 해제하는 방법

"What is the memory overhead of storing data in a .NET DataTable?"스레드의 허용 대답의 제안처럼 DataTable에서 관련 데이터를 이동하려고합니다. 내가 지우기를 사용하여 폐기하고 다음 스레드에서 제안되어 있기 때문에 null로 설정하고있어

GC.Collect(); // force the garbage collector to free memory 
// First stop point - Total process memory (taskmanager) = 900 MB 
List<ExpandoObject> ExpandoList = new List<ExpandoObject>(); 
foreach (DataRow drTest in dtTest.Rows) 
{ 
    dynamic ExpandoItem = new ExpandoObject(); 
    ExpandoItem.FieldName = drTest["FieldName"].ToString(); 
    ExpandoList.Add(ExpandoItem); 
} 
// Second stop point - Total process memory (taskmanager) = 1055 MB 
dtTest.Clear(); 
dtTest.Dispose(); 
dtTest = null; 
GC.Collect(); // force the garbage collector to free memory 
// Third stop point - Total process memory (taskmanager) = 1081 MB (wtf? even more!) 

:

Datatable.Dispose() will make it remove from memory?가 종점 코멘트가 포인트가에 메모리 사용량을 확인하십시오이 내 코드입니다. 나는 또한 (DataTable dtTest = ...)를 사용하여 시도했지만 결과는 동일했다.

내가 뭘 잘못하고 있니? DataTable에서 데이터를 축소하는 더 좋은 방법이 있습니까?

+0

메모리 프로파일 러를 실행하고 데이터 테이블 (또는 큰 크기의 것)이 아직 참조되고 있는지 확인하십시오. – fejesjoco

+0

dtTest는 어디에서 왔습니까? 메소드 호출에 대한 매개 변수입니까? 그렇다면 호출 메소드에 의해 계속 참조되므로 가비지 콜렉션에 적합하지 않습니다. –

+0

같은 기능에서 온 것입니다. 문제는 작업 관리자를 사용하여 메모리 크기를 확인하는 것이 었습니다. 나는 .NET에 예약 된 메모리가 있다는 것을 알지 못했다. – Undercover1989

답변

3

나는 마지막으로 메모리 사용에 대한이 스레드를 발견

윈도우 작업 관리자가 .NET 응용 프로그램의 메모리 사용량을 측정하는 데 사용해서는 안 : .NET EXE memory footprint

허용 된 대답은 다음과 말했다.

.NET 응용 프로그램이 시작되면 운영 체제에 메모리 덩어리를 요청한 다음 을 관리 힙, 스택 및 대형 개체 힙으로 세그먼트 화합니다. TaskManager가보고하는 것은 메모리 의 총 덩어리이며 .NET에 의해 완전히 사용되거나 그렇지 않을 수 있습니다. .NET 응용 프로그램에 메모리 덩어리가 제공되면 운영 체제에서 묻는 메시지가 표시 될 때까지이를 해제하지 않습니다. 은 OS에서만 발생하며 더 많은 메모리 리소스가 필요합니다.

메모리 할당을 측정하려면 다양한 성능> 모니터 (PerfMon) 카운터를 확인해야합니다.

간단히 말해서 : 작업 관리자는 실제로 사용되는 대신 예약 된 메모리를 표시합니다. 즉, DataTable을 null로 설정하면 문제가 없습니다.

은 다음 코드로 실제로 사용 된 메모리를 얻기 위해 GarbageCollector를 사용할 수있다 :

long lMemoryMB = GC.GetTotalMemory(true/* true = Collect garbage before measuring */)/1024/1024; // memory in megabytes 

내가 내 코드와 함께이 시도하고 데이터 테이블의 제거가 28메가바이트에 의해 사용 된 총 메모리를 감소시켰다. DataTable에서 다른 컨테이너로 데이터를 추출하려는 노력만큼 가치가 없습니다. -/

같은 문제가있는 다른 사람들에게 도움이되기를 바랍니다.