2

私のアプリケーションでは、ユーザーは本のようにピボットを使用し、最後に当たるまでピボットアイテムを反転します。次に、既存のピボットアイテムを削除して、新しいアイテムをロードします。これはすべて、Pivot.ItemsSourceプロパティを新しいアイテムのコレクションにポイントするだけで実行されます。

時間の経過とともにメモリ消費量が増加し、低下することはないことに気づきました。PivotのVisualTreeはガベージコレクションを取得していないようです。

問題を示すためのサンプルアプリケーションを作成しました(これはWP8アプリです)。

再現する手順:

  • アプリを起動
  • Page1に移動します
  • [さらに読み込む]ボタンを数回クリックします。

    (一度に100個のアイテムをロードしますが、これはもちろん実際のアプリケーションでは行いませんが、メモリ消費量が毎回高くなり、戻ってもクリアされないことを明確に示しています)

メモリを下げるためのヒントや提案をいただければ幸いです。このように長時間使用すると、必然的にアプリがクラッシュします。

MainPage.xaml:

...
<HyperlinkButton NavigateUri="/Page1.xaml">
    Page1
</HyperlinkButton>
...

MainPage.xaml.cs:

    //...
    public MainPage()
    {
        InitializeComponent();
        var timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromSeconds(2);
        timer.Tick += delegate
                          {
                              Debug.WriteLine("{0:f} MB, {1:f} MB",
                                              DeviceStatus.ApplicationCurrentMemoryUsage/(1024.0*1024),
                                              DeviceStatus.ApplicationPeakMemoryUsage/(1024.0*1024));
                          };
        timer.Start();
    }
    //...

Page1.xaml:

<Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" />
            <TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" />
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

            <StackPanel>
                  <phone:Pivot x:Name="pivot1" ItemsSource="{Binding Items}">
                    <!--Pivot item one-->
                    <phone:Pivot.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding}" />
                        </DataTemplate>
                    </phone:Pivot.ItemTemplate>
                </phone:Pivot>
                <Button Click="Load_More">Load More</Button>
            </StackPanel>
        </Grid>
    </Grid>

Page1.xaml.cs:

public partial class Page1 : PhoneApplicationPage, INotifyPropertyChanged
    {
        private List<int> _items;
        public List<int> Items
        {
            get
            {
                if (_items == null)
                {
                    _items = new List<int>();
                }
                return _items;
            }

            set
            {
                _items = value;
                RaisePropertyChanged("Items");
            }
        }
        public Page1()
        {
            InitializeComponent();
            DataContext = this;
        }

        private void Load_More(object sender, RoutedEventArgs e)
        {
            var lst = new List<int>();
            //100 new items just for demonstration, in reality i won't have more than 6 new items
            for (int i = 0; i < 100; i++)
            {
                lst.Add(i);
            }
            pivot1.SelectedIndex = 0;
            Items=lst;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        void RaisePropertyChanged(string property)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(property));
            }
        }

      ~Page1()
      {
          Debug.WriteLine("Page1 GC");
      }
    }
4

3 に答える 3

2

代わりにPanoramaコントロールを使用して示されているように、Pivo​​tコントロールがリークしているようです。スタックパネルをこれに置き換えても(コントロールの名前は変更していません)、リークは発生しません。(メモリは約50メガバイトで再生されます)

        <StackPanel>
            <Button Click="Load_More">Load More</Button>
            <phone:Panorama x:Name="pivot1" ItemsSource="{Binding Items}">
                <phone:PanoramaItem></phone:PanoramaItem>
            </phone:Panorama>
        </StackPanel>
于 2013-03-01T05:50:06.110 に答える
1

回避策の1つは、新しいコレクションを作成するのではなく、同じアイテムのコレクションを再利用し続けることです。変更する必要がある場合は、コレクションをクリアしてから再入力してください。コレクションは、たとえば次のようにアプリのグローバルスペースに存在する可能性があります。

public partial class App : Application
    {
        public static List<int> GlobalList;
...
    }

MainPageコンストラクターで初期化し、を介して参照しApp.GlobalListます。

于 2013-03-28T17:53:34.427 に答える
1

解決策1

おそらく、このソリューションを試すことができます:Windows Phone 8:LongListSelectorのメモリリーク

ページを閉じる前に、これらの依存関係のプロパティをクリーンアップしてみてください。

解決策2

バインディングOservableCollection<T>の代わりに使用してみてください。aをにバインドすると、 WPFの設計によりメモリリークが発生する可能性があります。List<T>ItemsourceList<T>Itemsource

Windows Presentation Foundationでデータバインディングを使用すると、メモリリークが発生する可能性があります

于 2014-03-18T09:43:39.933 に答える