2013-08-08 2 views
9

WP8アプリとその画像ビューアをテストして、多くの画像を表示しています。アプリのメモリ消費量が増えています。Windows Phone 8でBitmapImage/Imageコントロールのメモリが消費されています。

私はウェブからいくつかの記事を読んだことがありますが、それらの記事で提供されている解決策は私のアプリでは機能していません。下記の履歴をお読みください。

最初に、記事「Image Tips for Windows Phone 7」を見つけて、そのサンプルをダウンロードして、画像キャッシュテストを行いました。1画像で作業しています。

このアプリケーションをテスト目的でオフラインの画像でコンパイルし、 "コンテンツ"として設定しました。hereからテストアプリをダウンロードしてください。

私のテスト手順は、次のとおりです。

(1) Launch app 
(2) Go to Image Caching page 
(3) Enable checkbox "Avoid Image Caching" 
(4) Continuously tapping button Show/Clear 
(5) Keep watching the memory status textblock at the bottom 

私は16.02メガバイト =>ショー(19.32メガバイト)=>クリア(16.15メガバイト)のように、メモリを上げて、私のアプリをテストしていた場合=>表示(20.18MB)=>クリア(17.03MB)... etc キャッシュページを残してもメモリは解放されず、再びキャッシュページに移動します。 記事 "Image Tips for Windows Phone 7"の解決策は、1画像のためだけに働いているようです。

解決策のxamlとコードビハインドは「Image Tips for Windows Phone 7」となります。

[Caching.xaml]

 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 
      <StackPanel Orientation="Horizontal" VerticalAlignment="Top"> 
       <ToggleButton Content="Show" Width="150" Checked="ShowImageClicked" Unchecked="ClearImageClicked"/> 
       <CheckBox x:Name="cbAvoidCache" Content="Avoid Image Caching"/> 
      </StackPanel> 
      <Image x:Name="img" Grid.Row="2" Width="256" Height="192"/> 
      <TextBlock x:Name="tbMemory" Grid.Row="2" Text="Memory: " VerticalAlignment="Bottom" Style="{StaticResource PhoneTextLargeStyle}"/> 
     </Grid> 

[Caching.xaml.cs]

public partial class Caching : PhoneApplicationPage 
{ 
    public Caching() 
    { 
     InitializeComponent(); 

     DispatcherTimer timer = new DispatcherTimer(); 
     timer.Interval = TimeSpan.FromMilliseconds(500); 
     timer.Start(); 
     timer.Tick += delegate 
     { 
      GC.Collect(); 
      tbMemory.Text = string.Format("Memory: {0} bytes", DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage")); 
     }; 
    } 

    private int nIndex = 1; 
    BitmapImage bitmapImageFromUri = new BitmapImage(); 
    private void ShowImageClicked(object sender, RoutedEventArgs e) 
    { 
     string strImage = string.Format("../ImagesAsContent/{0:D2}.jpg", nIndex); 
     bitmapImageFromUri.UriSource = new Uri(strImage, UriKind.Relative); 
     img.Source = bitmapImageFromUri; 

     nIndex++; 
     if (nIndex > 15) 
     { 
      nIndex = 1; 
     } 

     (sender as ToggleButton).Content = "Clear"; 
    } 

    private void ClearImageClicked(object sender, RoutedEventArgs e) 
    { 
     if (cbAvoidCache.IsChecked == true) 
     { 
      // set the UriSource to null in order to delete the image cache 
      BitmapImage bitmapImageFromUri = img.Source as BitmapImage; 
      bitmapImageFromUri.UriSource = null; 
     } 
     img.Source = null; 
     (sender as ToggleButton).Content = "Show"; 
    } 
} 

Iはまた、他の解決策を検索しようと、いくつかのテストの結果は以下の通りです。

(1)記事「[wpdev] Memory leak with BitmapImage」:2つのソリューションを提供します.1つはDisposeImage APIです。もう1つはBitmapImageソースをnullに設定することです。また、この記事ではイベントハンドラのアタッチ/デタッチについて注意する必要があることを知っていますが、テストアプリケーションにはキャッシュページにイベントハンドラがありません。

[DisposeImage]

private void DisposeImage(BitmapImage image) 
{ 
    if (image != null) 
    { 
     try 
     { 
      using (var ms = new MemoryStream(new byte[] { 0x0 })) 
      { 
       image.SetSource(ms); 
      } 
     } 
     catch (Exception) 
     { 
     } 
    } 
} 

[設定のヌル]

BitmapImage bitmapImage = image.Source as BitmapImage; 
bitmapImage.UriSource = null; 
image.Source = null; 

(2)条 "Windows phone: listbox with images out-of-memory":それは(1より少し差がAPI "DisposeImage" を提供)のように、これも動作しませんが、私はまだメモリを症状を起こしている。

public static void DisposeImage(BitmapImage image) 
{ 
    Uri uri= new Uri("oneXone.png", UriKind.Relative); 
    StreamResourceInfo sr=Application.GetResourceStream(uri); 
    try 
    { 
    using (Stream stream=sr.Stream) 
    { 
     image.DecodePixelWidth=1; //This is essential! 
     image.SetSource(stream); 
    } 
    } 
    catch 
    {} 
} 

(3)条「Cannot find the memory leak」:それは言及した上記と同じ2つのソリューションを提供し、また、それは問題はしかし、私のテストのアプリの画像が分離ストレージからある、分離ストレージのイメージにREPROすることはできません述べました。

(4)Iはまた、1000枚の画像に対して試み、試験結果は、アプリケーションが順次周りに190の画像を示した場合、以下メモリのためのWindows Phoneアプリケーション分析グラフィックを参照してくださいアプリクラッシュあります。 enter image description here

最後に、私の質問と歴史を読んでいただき、ありがとうございました。私は何日も解決策を見つけるためにこれに取り組んできました。 手掛かりや解決策がありましたら、お知らせください。

ありがとうございました。

+1

良い質問は、同じ問題を抱えています。ここにどんなニュース? –

+0

まだ解決策を探しています。明らかに、これはWP7.5のバグです。つまり、WP8のみをターゲットにしていない場合、WP8でも発生します。 –

答えて

3

実際に私は、回避策を見つけたことを、最後に、私は同じ問題を扱っていたと私は思う、私はプロのプログラマーはないですが、ここに私のソリューションです:

public Task ReleaseSingleImageMemoryTask(MyImage myImage, object control) 
    { 
     Pivot myPivot = control as Pivot; 
     Task t = Task.Factory.StartNew(() => 
     { 
      Deployment.Current.Dispatcher.BeginInvoke(() => 
      { 
       if (myImage.img.UriSource != null) 
       { 
        myImage.img.UriSource = null; 
        DisposeImage(myImage.img); 
       } 
       PivotItem it = (PivotItem)(myPivot.ItemContainerGenerator.ContainerFromIndex(myImage.number % 10)); 
       Image img = FindFirstElementInVisualTree<Image>(it); 
       if (img != null) 
       { 
        img.Source = null; 
        GC.Collect(); 
       } 
      }); 
      myImage.released = true; 
     }); 
     return t; 
    } 


private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject 
    { 
     var count = VisualTreeHelper.GetChildrenCount(parentElement); 
     if (count == 0) 
      return null; 

     for (int i = 0; i < count; i++) 
     { 
      var child = VisualTreeHelper.GetChild(parentElement, i); 

      if (child != null && child is T) 
      { 
       return (T)child; 
      } 
      else 
      { 
       var result = FindFirstElementInVisualTree<T>(child); 
       if (result != null) 
        return result; 
      } 
     } 
     return null; 
    } 

    private void DisposeImage(BitmapImage img) 
    { 
     if (img != null) 
     { 
      try 
      { 
       using (var ms = new MemoryStream(new byte[] { 0x0 })) 
       { 
        img = new BitmapImage(); 
        img.SetSource(ms); 
       } 
      } 
      catch (Exception e) 
      { 
       System.Diagnostics.Debug.WriteLine("ImageDispose FAILED " + e.Message); 
      } 
     } 
    } 

・ホープこのヘルプ:)

+0

こんにちはダミアン、あなたの応答に感謝、私は今、この問題をテストしていないよけれども、あなたの答えのためにまだ感謝。あなたは 'IMG =新しいBitmapImageの()を呼び出して画像を配置しようとすると、 –

+0

はここhttp://stackoverflow.com/questions/24161008/coverflow-with-out-of-memory – user2056563

+1

を助けてください;'。全体の目的を破ることはありませんか? VaRのMS =新規のMemoryStream(新しいバイト[] {を0x0})とimg.SetSource(MS:彼はソースとして、メモリの0バイトのブロックを割り当てている新しいオブジェクトを割り当てている間 – thumbmunkeys

関連する問題