3

축소판 목록을 보여주는 Windows phone 응용 프로그램을 만들고 있습니다. 나는 그것을하기 위해 LongListSelector를 사용하고있다.WP8 메모리 누수 개폐 PhoneApplicationPage

섬네일 목록을 앞뒤로 탐색 할 때 메모리 누수가 발생합니다. 앱을 사용하는 동안 메모리 사용량을 검토하고 미리보기 이미지가있는 페이지를 열면 메모리가 증가하는 것을 볼 수 있습니다 (예상대로). 이전 페이지로 돌아 가면 메모리 사용량이 감소하지만 증가하지는 않습니다. 처리를 여러 번 반복하면 메모리 부족 예외로 종료됩니다.

두 페이지 만있는 테스트 응용 프로그램을 만들었습니다. 하나는 LongListSelector에서 potos 세트를로드하는 다른 버튼으로 이동하는 단추입니다. 나는 메모리 누출이 다른 것에 의해 야기되지 않았 음을 확실히하기 위해이 App을 만든다.

이 간단한 테스트에서 메모리 사용량은 내 응용 프로그램에서와 같이 작동합니다. 여기

는 thumbnais 내 페이지의 주요 코드 :

public class testObject 
{ 
    public string Title { get; set; } 
    public BitmapImage Thumbnail { get; set; } 
} 

protected override void OnNavigatedTo(NavigationEventArgs e) 
{ 

    photosList = new List<testObject>(); 
    for (int i = 0; i < 200; i++) 
    { 
     BitmapImage bi = new BitmapImage(new Uri("/images/" 
             + i.ToString()+".jpg", 
             UriKind.RelativeOrAbsolute)); 


     photosList.Add(new testObject { Title = i.ToString(), 
              Thumbnail = bi }); 
    } 

    GridPictures.ItemsSource = photosList; 

} 

protected override void OnBackKeyPress(
      System.ComponentModel.CancelEventArgs e) 
{ 
    foreach (testObject test in photosList) 
    { 
     test.Thumbnail.DecodePixelHeight = 1; 
     test.Thumbnail.DecodePixelWidth = 1; 
     test.Thumbnail = null; 
    } 
    photosList.Clear(); 
    photosList = null; 

    base.OnBackKeyPress(e); 
} 

그리고 여기에 다른 페이지에있는 버튼의 코드입니다 :

private void Button_Click_1(object sender, RoutedEventArgs e) 
{ 
    NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.RelativeOrAbsolute)); 

} 
+0

'OnBackKeyPress' 내부에서'GC.Collect(); '를 사용해 보셨습니까? – Romoku

+0

가능한 중복 : http://stackoverflow.com/questions/13816569/windows-phone-listbox-with-images-out-of-memory –

답변

3

LongListSelector 누수의 알려진 소스 . 많은 양의 메모리를 사용하는 Image과 같은 컨트롤을 사용하면 이러한 누수가 특히 문제가됩니다.

지금까지 가장 좋은 해결책은 LongListSelector를 피하는 것이 었습니다. OnNavigatedFrom 경우에, 사진의 해방을 강제로 페이지 1에서

  • :하지만 당신이 적절한 대안을 찾을 수 없습니다, 당신은 몇 가지 해결 방법이 있습니다. 이 그렇게 할 수있는 몇 가지 방법은, 그러나 일반적으로 null로 ImageSource 속성을 설정하는 것은

사용자 정의 컨트롤을 같이 할 수

  • 당신을 위해 더러운 일을 할 수있는 사용자 지정 컨트롤을 확인 충분하다 :

    public class SafePicture : System.Windows.Controls.ContentControl 
    { 
        public SafePicture() 
        { 
         this.Unloaded += this.SafePictureUnloaded; 
        } 
    
        private void SafePictureUnloaded(object sender, System.Windows.RoutedEventArgs e) 
        { 
         var image = this.Content as System.Windows.Controls.Image; 
    
         if (image != null) 
         { 
          image.Source = null; 
         } 
        } 
    } 
    

    그럼, 그냥 컨트롤에있는 모든 사진 포장 :

    <my:SafePicture> 
        <Image Source="{Binding Path=Thumbnail}" /> 
    </my:SafePicture> 
    

    그리고 그 트릭을해야합니다. 여전히 메모리 누출이 있지만 훨씬 더 합리적인 금액입니다.