2012-04-19 3 views
2

MVVM Prism을 사용하여 작성된 WPF 응용 프로그램이 있습니다. 그것은 많은 탭이 있습니다. 이러한 탭은 각각 약 2..3 MB의 메모리를 사용합니다. 클라이언트는 수십 개의 탭을 열고 닫은 후에 처음부터했던 것보다 훨씬 많은 메모리를 사용한다는 불평을합니다. 또한 새 탭을 열면 더 많은 메모리가 필요하므로 응용 프로그램에서 이전 탭을 사용하지 않고 대신 새 탭을 만듭니다.WPQ에서 메모리 누수가 발생했습니다. MVVM Prism 앱

분명히 오래된 탭은 가비지 수집되지 않습니다. 분명히 그들을 가리키는 몇 가지 링크가 있기 때문에.

어떻게하면 어떤 방법으로 가비지 수집합니까? 내가 IDisposable을 구현하고 가능한 모든 참조를 제거해야합니까? 그리고 Dispose 메서드가 소멸자에서도 호출되는지 확인하십시오. 불필요한 참조를 모두 제거 할 수 있는지 확신 할 수 없습니다.

아마도이 문제를 해결하는 데 사용할 수있는 유용한 도구가 있습니까?

+0

진실하지 않을 수 있습니다 예를 들어, 내 폐기에 우리는 같은 것을했다. GC가 가비지 수집과 같은 느낌이 들지 않으면 참조가 없어도 메모리에 남아 있습니다. – stijn

+0

@stijn GC.Collect라고 불렀지 만 여전히 메모리에 머물러 있습니다. –

답변

4

이것은 분명히로드 된 질문입니다. 메모리 소비는 메모리 누수로 인한 것일뿐만 아니라! 모든 앱이 다르며 은색 글 머리 기호가 없으므로 도움이 될만한 아이디어가 여기에 있습니다.

  1. ANTS 프로파일 러를 얻으려면 2 주간의 시험 사용 기간 + 훌륭한 자습서가 있어야합니다. 그것은 zomby 객체와 같은 많은 것들을 가리킬 것입니다.

  2. WPF는 돼지입니다. 따라서 더 많은 탭을 열면 더 많은 메모리를 사용할 수 있습니다. XAML을 살펴본 다음 트리밍 할 수 있습니까? 예를 들어 레이블 대신 TextBlock을 사용하십시오. StackPanel 내의 StackPanel, Grid 내의 Grid, 스택 패널 내에서 추가 중첩 컨트롤을 제거합니다. 모든 격자를 하나의 격자에 넣고 행/열을 사용합니다. 각 항목이 수행하는 항목 템플릿이있는 경우 복잡하다. 예를 들어 초점이 맞으면 항목 주위에 경계선이 생기고 멋진 점이 있습니다. 질문을하고 각 항목에서 해당 항목을 제거하고 해당 위치를 계산하고 적절하게 위치를 지정하는 컨트롤 하나를 만들 수 있습니다.

  3. 동일한 유형, 다른 인스턴스의 탭 당보기 (사용자 정의 컨트롤 또는 컨트롤)가 있습니까? 그렇다면 재활용 할 수 있습니까? 저는 몇 년 전에 몇 가지 메뉴를 사용하여 몇 가지 기준에 맞는 탭을 만들고 다른 탭에 대한 탭을 만드는 프로젝트를 진행했습니다. 기준은 다르지만보기 유형은 동일합니다. 그것은 단지 다른 정보로 주입되었습니다. Prism은 분명히 비싸지 만이 탭 각각에 대해 새로운 View 컨트롤을 작성했습니다. 우리가 한 일은 결국 다른 ViewModel을 만드는 것이지만, 그 값 비싼보기의 동일한 인스턴스 (해당 지역에 필요할 때 제거/다시 추가하여 재활용)를 유지하는 것입니다. 은 이렇게하려면 각각의 ViewModel이 링크가 유용 할 수 있습니다

    것 탐색에 (샘플)

    //detaching from Prism region allows for recycling 
    public override void OnNavigatedFrom (NavigationContext navigationContext) 
    { 
    var view = _container.Resolve (typeof (Object), "NameOfTheView"); 
    if (view != null) 
        navigationContext.NavigationService.Region.Remove (view); 
    } 
    //similarly you can readd it where your think it is nedded.. 
    
    public override void OnNavigatedTo (NavigationContext navigationContext) 
    { 
        base.OnNavigatedTo (navigationContext); 
        RestoreDataState (_state); 
    

    } : 가비지 수집에 http://blogs.msdn.com/b/dphill/archive/2011/01/23/closable-tabbed-views-in-prism.aspx

  4. 참고 : 의 .NET의 전체 목적 가비지 컬렉터는 우리를 대신하여 메모리를 관리하는 것입니다. 그러나 매우 드문 경우이지만 GC.Collect()를 사용하여 프로그래밍 방식으로 가비지 수집을 수행하는 것이 좋습니다.

    특히 : 응용 프로그램이 가능한 가비지 수집 중단하지 않으려는 코드 블록에 입력하는 것입니다 a.When

    .

    b. 응용 프로그램이 매우 많은 수의 객체를 할당하고 방금 획득 한 메모리를 최대한 빨리 제거하려고 할 때. (내 프로젝트의 경우)

    c. 또한 : http://blogs.msdn.com/b/ricom/archive/2004/11/29/271829.aspx

내가 확실히 내가 null로 큰 모든 것을 설정합니다 모든 뷰 모델에 폐기 방법을 구현하는 것이, 이벤트에서 탈퇴하는 것을 잊지하고, 타이머 같은 것들을하지 않습니다. GC.Collect()를 호출 할 수 있습니다. 위의 주석을 읽으십시오. 복잡한 객체를 정리하는 것을 잊지 마세요. null로 설정하지 마십시오. 결과적으로이 일을했다

ClearDisplayGrid(); 

: "자신을 가리키는 몇 가지 링크가 있기 때문에 분명히"

private void ClearDisplayGrid() 
    { 
     foreach (var r in DisplayGrid.MyItems.SelectMany (it => it.SubItems)) 
     { 
      r.IsSelectedChanged -= ReadingIsSelectedChanged; 
      r.InEditChanged -= ReadingInEditChanged; 
      r.PropertyChanged -= ReadingPropertyChanged; 
     } 
    } 
+0

ANTS 메모리 프로파일 러를 사용하여 일부 뷰의 객체를 참조하는 클래스가 있음을 확인했습니다. 이러한 참조는 뷰와 ViewModel을 수집하지 못하게합니다. 아직 해결하지 못했지만 실제 문제를 안다면 문제는 완전히 달라집니다. –

+0

매우 멋지다. 예, ANTS가 정말 저에게 자신을 증명했습니다. –