파일의 일부 데이터 (예 : 1.00E + 7 개체)를 개체 목록으로 읽습니다. 그런 다음 각각을 변환하여 디스크에 직렬화하는 다른 클래스로 전달합니다. 이 과정에서 나는 상당한 메모리 누수가있다.C# GC가 루트가없는 개체를 수집하지 않습니다.
사용 !dumpheap -stat
나는 내 수업의 일부는 다음과 같은 메모리를 많이 차지하는 것을 볼 수 :
MT count TotalSize ClassName
00185fd0 196180 7847200 Di3BMain.PeakDataClass
0070d25c 392429 9418296 System.Collections.Generic.List`1[[DI3.Lambda`2[[System.Int32, mscorlib],[Di3BMain.PeakDataClass, Di3Main]], Di3]]
00707038 392360 10986080 DI3.B`2[[System.Int32, mscorlib],[Di3BMain.PeakDataClass, Di3Main]]
00930a0c 15453 12821476 CSharpTest.Net.Collections.BPlusTree`2+Element[[System.Int32, mscorlib],[DI3.B`2[[System.Int32, mscorlib],[Di3BMain.PeakDataClass, Di3Main]], Di3]][]
7282fe8c 393241 13307220 System.Object[]
72843a70 250 641899364 System.Int32[]
이 번호가 같은 객체의 인스턴스가 생성되는 것이 분명 크기를 고려하면, 나는 예상대로 (하나의 입력 객체에 대해 하나의 출력 serializ 객체). 내 코드에서 예상대로 그러나 새로운 각 개체를 수집해야하는 매우 단순화 된 형식으로 된 다음과 같습니다 :
serializer.Add(new ConvertedObject(...){ ... });
내가 가장 큰 항목 중 일부의 뿌리를 확인하기 위해 노력 누출을 이해하기; 예를 들어 MT: 00707038
을 사용하면 !gcroot -all 00707038
; 하지만 그것은 나를주는 것은 Found 0 roots.
감안할 때 단지 모든 통계 전에 강제 것을 GC
내가 GC
없이 뿌리와 그 큰 개체 중 하나를 수집하지 않는 이유를 궁금해, 다음 코드를 사용하여입니까?! 심지어 그것을 밀고 난 후에!
GC.Collect();
GC.SuppressFinalize(this);
GC.WaitForPendingFinalizers();
GC *가 (루트에서 액세스 할 수없는 경우) 개체를 수집 할 수 있기 때문에 즉시 그렇게해야한다는 것을 의미하지는 않습니다. 언제든지 개체를 수집 할 수 있습니다. 또한 코드를 표시하지 않았습니다. – Servy
@Servy - he calss GC.Collect() –
@HenkHolterman 기술적으로 이것은 콜렉션을 수행하기위한 요청 일뿐입니다. 하나는 GC가 원한다면 무시할 수 있습니다. 그럼에도 불구하고 문제는 재현 가능한 예가 부족합니다. 컬렉션을 수행 할 때 객체에 액세스 할 수 있습니다. – Servy