2013-04-20 2 views
4

코드가 쓰레기를 생성하는지 여부를 감지하고 싶었습니다. 그래서 다음 단위 테스트를 만들었습니다.유닛 테스트에서 쓰레기 감지

[TestClass] 
public class AllocationTest 
{ 
    int[] generationCollections = new int[3]; 

    [TestMethod] 
    public void TestGarbageGeneration() 
    { 
     generationCollections[0] = GC.CollectionCount(0); 
     generationCollections[1] = GC.CollectionCount(1); 
     generationCollections[2] = GC.CollectionCount(2); 

     // Test for garbage here 

     for (int generation = 0; generation < generationCollections.Length; generation++) 
     { 
      Assert.AreEqual(GC.CollectionCount(generation), generationCollections[generation]); 
     } 
    } 
} 

"여기에 쓰레기 테스트"코멘트가 있고 결과를 예측할 수없는 코드를 넣습니다. 내 이해는 이것이 GC가 별도의 스레드에서 실행되며 언제든지 내 테스트 이외의 코드에 의해 트리거 될 수 있기 때문입니다.

GC.Collect를 사용하여 테스트 코드 전후에 강제로 컬렉션을 실행했지만 컬렉션 수를 늘리면 항상 테스트가 실패합니다.

단위 테스트에서 가비지를 테스트하는 의미있는 방법이 있습니까?

+0

[가능한 단위 테스트의 메모리 사용을 프로파일 링 할 수 있습니까?] (http://stackoverflow.com/questions/2930172/is-it- 가능한 프로필 메모리 사용량 단위 테스트) –

+0

"항상 수집 횟수를 증가시킵니다."그렇습니다. – GameAlchemist

답변

1

WMemoryProfiler을 사용하면 몇 가지 추가 유형이 만들어 졌는지 확인할 수 있습니다. 자신 만의 프로세스를 프로파일 링하면 추가로 생성 된 모든 유형 + WMemoryProfiler에서 보고서를 생성하는 데 사용되는 일부 인스턴스가 생성됩니다.

별도의 프로세스를 사용하여 관리 힙을 모니터링하거나 자신의 유형으로 만 제한함으로써 해결할 수 있습니다. 메모리가 누출되면 일반적으로 사용자가 만든 추가 인스턴스에서 메모리를 보게됩니다.

using (var dumper = new InProcessMemoryDumper(false,false)) 
    { 
    var statOld = dumper.GetMemoryStatistics(); 

    // allocaton code here 
    var diff = dumper.GetMemoryStatisticsDiff(statOld); 

    foreach (var diffinst in diff.Where(d => d.InstanceCountDiff > 1)) 
    { 
     Console.WriteLine("Added {0} {1}", diffinst.TypeName, diffinst.InstanceCountDiff); 
    } 
    } 

당신은 많은 메모리의 임시 객체를 사용했던 방법은 CLR에 의해 generaeted ETL 추적을 사용하지 PerfView 같은 몇 가지 프로파일 링 API 또는 도구를 사용해야합니다 후 경우. GC의 경우 프로그래밍 방식으로 특정 항목을 활성화해야합니다. 나는 GCAllocationTick_V1 이벤트가 귀하의 경우에도 흥미로울 것이라고 생각합니다.

diff를 얻기 전에 개체에 대한 참조를 유지하면 개체 그래프가 소비 할 메모리 양을 잘 이해할 수 있습니다. 당신이 을 시도 할 수 있습니다 무엇

1

실제로

// do some logic 

    // GC.Collect, Thread.Sleep, ... 

    currentCollections[0] = GC.CollectionCount(0); 
    currentCollections[1] = GC.CollectionCount(1); 
    currentCollections[2] = GC.CollectionCount(2); 

및 BTW 첫 번째 매개 변수는 주장에 (이 덤프 값으로 주장하는 할 후 같은 주장하기 전에 GC 상태를 덤프 정확히 같은 논리를 사용하는 것입니다 기대, 그리고 두 번째는

for (int generation = 0; generation < generationCollections.Length; generation++) 
    { 
     Assert.AreEqual(generationCollections[generation], currentCollections(generation)); 
    } 

그래서이 대부분의 경우 작동하지만 GC를 만들 수있는 방법은 없습니다 뭔가를 할 수 있습니다) 실제 - 당신 수도 단지 그런 다음에 뭔가를하고 믿음으로 기다리십시오.

+0

실수를했습니다. "여기에있는 가비지 테스트"주석은 가비지를 생성 할 수있는 코드가있는 곳입니다. 실제 테스트는 주장입니다. – RecursiveCall

관련 문제