2017-04-08 3 views
2

은 내 경우에는이 .NET에서 런타임에 "관련성이없는"코드를 감지하고 그 안에 개체를 가비지 수집 할 수 있습니까?

public void foo(){ 
    Object very_large_object; 
    if (very_large_object.some_runtime_condition()) { 
     do_something(); 
     return; 
    } 
    do_something_else (very_large_object); 
} 

같은 C#을 방법은 do_something 비싼 방법이며 완료하는 데 약간의 시간이 걸릴 수 있다고 가정하자. 실행 중일 때 .NET GC가 do_something_else이 호출되지 않으므로 very_larget_object은 더 이상 관련이없고 가비지 수집 할 수 있습니까?

+0

very_large_object 만 _ 인스턴스화하면 if 절이되므로 필요한 경우에만 인스턴스화 할 수 있습니까? –

+0

@GianPaolo 내 코드를 지나치게 단순화 한 것처럼 보입니다 ... 조건은 실제로'very_large_object'에 달려 있습니다. 하지만 나는 그것이 안전 할 수 있도록 null로 설정해야한다고 생각합니다. – sqd

답변

1

예. 가능합니다. 개체 수명이 둘러싸는 범위와 어떻게 든 관련이 있다는 것은 일반적인 오해입니다 (예 : foo 범위가 끝나면 very_large_object 만 수집 할 수 있음). 당신은 간단한 응용 프로그램과 함께 당신의 특별한 경우를 확인할 수 있습니다

class Program {   
    static void Main() { 
     var o = new TestObject(); 
     var test = Console.ReadKey(); 
     if (test.Key == ConsoleKey.Enter) { 
      DoSomething();    
      Console.ReadKey(); 
      return; 
     } 
     DoSomethingElse(o); 
    } 

    static void DoSomething() { 
     Console.WriteLine("doing something"); 
     Thread.Sleep(500); 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
     Console.WriteLine("GC ran"); 
    } 

    static void DoSomethingElse(TestObject o) { 
     Console.WriteLine(o); 
    } 
} 

public class TestObject { 
    public TestObject() { 

    } 
    ~TestObject() { 
     Console.WriteLine("finalizer running"); 
    } 
} 

당신은 최적화와 릴리스 모드에서 활성화하는 컴파일하면 출력됩니다 (당신이 콘솔에서 Enter 키를 누릅니다 후) 다음 : 그래서

doing something 
finalizer running 
GC ran 

o은 가비지로 간주되어 우리가 여전히 DoSomething 메서드 안에있는 동안 finalizer 큐에 넣었습니다. Optimizer는 실행 여부에 상관없이 콘솔 입력에 따라 다르므로 DoSomethingElse으로 분기를 버릴 수 없습니다. return을 제거하면 당연히 수집되지 않습니다.

관련 문제