2015-09-15 14 views
19

UWPアプリケーションを開発しているうちに、私は最近、GCによるページの収集を妨げるメモリリークをかなり発見しました。私はコンテンツを削除、または動的バインディング{}でそれを交換した後UWPでコンパイルされたバインディングx:バインドによってメモリリークが発生する

<ContentControl Grid.Column="0" Grid.Row="1" Content="{x:Bind ViewModel.Schedule, Mode=OneWay}"> 
</ContentControl> 

- 私はそれから移動するときにページが収集されます。 は、私は私のページ上のContentPresenterなどを持っています。それ以外の場合は、メモリに残ります。 これはバグですか、何か間違っていますか?ナビゲートする際にすべてのバインディングを解放してクリアする方法はありますか?

UPDATE: hereを述べたとして、Microsoft内部の既知の問題のようです。 しかし、自分のテストやアプリケーションの使い方で見る限り、x:Bindによって保持されているデータは、同じページに移動したり、同じコントロールを作成したり時間。新しいオブジェクトが作成されたことがわかりましたが、ある時点で古いオブジェクトが収集されました。

私にとっては、メモリが不足しているという劇的な問題ではないようですが、動的バインディングと同じくらい速くオブジェクトを収集することはできません。

+0

@ O.O回答ありがとう!コンパイル済みバインディングのデフォルトモードはOneTimeなので、この場合はOneWayを指定するだけです。 [link](https://msdn.microsoft.com/en-us/library/windows/apps/mt204783.aspx) – Viachslau

+0

@OOに関するメモリリークについて私はプロファイラで次のような動作を見ました:バインディング - ページからナビゲートした後、各スナップショットにオブジェクトが収集されます。コンパイルされたバインディングでは、そうではありませんが、ある時点でDOが収集されますが、一部はまだ保存されています。 – Viachslau

+0

訂正していただきありがとうございます。私はアプリで同じ問題を抱えていますが、ダイナミックなバインディングを使用しており、前後にナビゲートすることに気づかないこと以外に問題を特定できなかったため、問題が悪化しました。 OnNavigatedTo/Fromイベントを使用して、datacontextとdatabindingsおよびナビゲーションスタックをクリアすることができます。あなたのシナリオで動作する場合は、ページキャッシュを有効にすることもできます。 –

答えて

1

はい、それはあなたが次の手順を使用することができることを防ぐために、メモリリーク原因を行います。UnityContainerよう

  1. 利用のIoCとあなたのViewModelまたはビューContainerControlLifeTime
  2. が一度xaml.csでのViewModelプロパティにnullを代入しますあなたはUIの外に出ます。
3

この問題のため、マイクロソフトの接続にバグがありました。

https://connect.microsoft.com/VisualStudio/feedback/details/3077894/memory-leaks-in-c-uwp-apps-using-compiled-x-bind-bindings

この問題を回避するには、明示的にページアンロードイベントハンドラでBindings.StopTracking()を呼び出すことです。コンパイルされたバインディングは「弱いイベント」パターンを使用せず、INotifyPropertyChangedのPropertyChangedイベントに直接サブスクライブするためです。これはメモリリークの原因です。イベントの登録を解除するには、Bindings.StopTracking()を呼び出します。コンパイルされたバインディングコードは自動的に呼び出されません。

+0

この問題を回避するには、Unloaded event handlerページでBindings.StopTracking()を明示的に呼び出します。コンパイルされたバインディングは「弱いイベント」パターンを使用せず、INotifyPropertyChangedのPropertyChangedイベントに直接サブスクライブするためです。これはメモリリークの原因です。イベントの登録を解除するには、Bindings.StopTracking()を呼び出します。コンパイルされたバインディングコードは自動的に呼び出されません。 –

関連する問題