10

WP8 アプリをテストしていますが、多くの画像を表示する画像ビューアーです。アプリのメモリ消費量が増えていることがわかり、解決方法を知りたいと考えています。

Web からいくつかの記事を読みましたが、それらの記事で提供された解決策がアプリで機能しません。以下の履歴をお読みください。

まず、「Windows Phone 7 の画像のヒント」という記事を見つけ、そのサンプルをダウンロードしてクリーンな画像キャッシュ テストを行ったところ、1 つの画像で動作しています。

そして、テスト目的で、このアプリをアプリ内に15 個のオフライン イメージでコンパイルし、「コンテンツ」として設定します。ここからテスト アプリをダウンロードしてください。

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

(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.02MB => Show(19.32MB) => Clear( 16.15MB ) => Show(20.18MB) => Clear ( 17.03MB )...などのようにメモリが増加しています そしてメモリキャッシングページを離れて再度キャッシングページに移動しても解放されません。記事「Windows Phone 7 の画像のヒント」の解決策は、 1 つの画像に対してのみ機能しているようです。

「 Image Tips for Windows Phone 7 」によるソリューションの xaml とコード ビハインドは次のとおりです。

[キャッシング.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>

[キャッシング.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";
    }
}

他の解決策も検索しようとしましたが、いくつかのテスト結果は次のとおりです。

(1) 記事「[wpdev] BitmapImage によるメモリ リーク」: DisposeImage API と、以下のように BitmapImage ソースを null に設定するという 2 つの解決策を提供します。また、この記事では、イベント ハンドラーのアタッチ/デタッチに注意する必要があることを知らせていますが、私のテスト アプリにはキャッシュ ページにイベント ハンドラーがありません。

[画像を破棄]

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: メモリ不足の画像を含むリストボックス」: 以下のように (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) 記事「メモリ リークが見つかりません」: 上記と同じ 2 つの解決策を提供します。また、分離ストレージのイメージでは問題を再現できないと述べていますが、私のテスト アプリのイメージは分離ストレージからのものです。

(4) 1000 枚の画像についても試しました。テスト結果は、アプリが約 190 枚の画像を連続して表示したときにアプリがクラッシュしました。メモリについては、以下の Windows Phone アプリケーション分析グラフィックスを参照してください。 ここに画像の説明を入力

最後に、私の質問と履歴をお読みいただきありがとうございます。解決策を見つけるために何日も取り組んできました。何か手がかりや解決策がありましたら、お手数ですが教えてください。

ありがとう。

4

1 に答える 1