2013-10-23 3 views
2

의 새로운 통해 가능한 메모리 누수가, 나는 그들이 내부에서 제거하는 동안이 목록은 항상 개체를 잡고 것을 관찰 디버깅하는 동안, 지금의 C# - 디버깅하는 동안 속성

public IEnumerable<ISomething> TheSomeThingList 
    { 
     get 
     { 
      var somethings = new List<ISomething>(); 

      // Fill the list by doing some iteration over internal dictionary of dictionaries 
      return somethings.AsEnumerable(); 
     } 
    } 

을 다음과 같이 코드를 건너 왔어요 사전. 이 목록에는 제거 된 객체에 대한 참조가 있으므로

이러한 코드로 인해 메모리 누수가 발생할 수 있습니까?

그렇다면이 문제의 해결 방법은 무엇입니까? 속성의 인터페이스는 변경할 수 없습니다.

내 첫 번째 반응은 내부 제거가 발생할 때마다 Backing Field Collection을 만들고이를 지우는 것입니다.

몇 세부 사항 -

  1. 위의 속성이 클래스는 해야하는 목록에 가득
  2. 객체 (단결을 통해이 아닌 싱글 톤 패턴을 통해 달성) 응용 프로그램 수준의 싱글입니다 특정 작업 후에 정리되어야합니다 (문서 닫기). 이러한 객체를 보유하면 가비지 수집이 허용되지 않습니다.
+3

반환 된 'IEnumerable'에 대한 참조를 보유하고 있으면 가비지 수집되지 않으며 그 안에 포함 된 개체도 GC되지 않습니다. 그러나 나는 그것을 "누출"이라고 부르지 않을 것이다. – crashmstr

+3

목록의 유효 기간은 호출자가 반환 된 'IEnumerable'을 보유하는 기간에 따라 결정됩니다. 분명히 기대되는 것은 그 이후에 열거 될 것입니다. 그건 아무것도 누설하지 않습니다. –

답변

7

해당 개체에 여전히 "생생한"참조가 있기 때문에 메모리 누수가 아닙니다. 그것들은 그 목록에 있고, 그 목록은 그 방법으로부터 반환되고 있습니다. 해당 객체 이 아닌 경우이 메소드 호출자는 삭제 된 객체에 액세스하는 것이므로 발생하지 않아야합니다. 해당 목록에 루팅 된 참조를 통해 더 이상 액세스 할 수 없으며 해당 목록의 항목 중 어느 것도 다른 곳에서 액세스 할 수없는 경우 요소와 목록을 가비지 수집 할 수 있습니다.

누수가 없습니다.

+0

+1이 너무 빠르다 ... – Steve

3

여전히 개체에 대한 참조가있는 IEnumerable이 있기 때문에 이것은 메모리 누수가 아닙니다. IEnumerable<ISomething>을 사용하는 사람이 더 이상 유효하지 않은 개체를 가지고있어 놀랄지도 모르므로 해당 개체를 삭제하지 마십시오.

IEnumerable에 보유하고있는 것이 무엇이든간에 객체 수명을 활성화 상태로 유지하고 있다면 속성에서 반환 된 내부 상태와 IEnumerable을 지우는 방법을 찾아야합니다.

관련 문제