6

WPF で構築した UI フレームワークでガベージ コレクションに問題があります。問題を理解していると思うので、引用符でメモリリークを使用しますが、解決策や回避策はありません。

この問題は、UIElements を作成しても表示しない場合に発生します。UI の観点から、仮想化されたリスト ビュー (GridView) を使用しています。したがって、すべての行が一度に表示されるわけではありません。私のユース ケースの 1 つで、すべての行を csv にエクスポートできる Export Rows 機能を作成しました。通常、行内のセルは文字列や整数などのプリミティブで構成されています。

注意が必要なのは、一部のセルが UIElements 自体であることです。これが、リストが仮想化される理由の 1 つです (一部を作成するためのコストは時間がかかり、メモリを浪費する可能性があります)。したがって、要求されたときにのみ UIElements を作成し、それらをキャッシュすることさえしません (コレクションの対象にするため)。

この問題は、行プロバイダーを介して列挙しているときにプロパティにアクセスすると発生します。UIElements が作成されて返され、そこから抽出されたデータが csv に書き込まれ、次の行が調べられます。このループでは、これらの行 (ViewModel クラス) への参照がないため、ガベージ コレクションの対象になると考えられます。そうではないようです。.Net Memory Profiler を使用して、「メモリ不足の例外」は、(Dispatcher からの) PriorityQueue の DispatcherOperation によって UIElements がメモリ内に保持されている結果であると推測しました。これは、表示されるのを待っているためだと思います(ただし、表示されることはありません)。

メモリ不足の例外が発生しない場合、これらの UIElements は PriorityQueue を介して処理されているように見え (あきらめていると思います)、ガベージ コレクションが行われます。これが最良のシナリオです。少数の行を扱っている場合、これは問題ないようです。しかし、50,000 ~ 100k レベルになると、話は別です。これらの ViewModels または UIElements 自体 (DispatcherOperation の外部) への他の参照がないことを保証できます。

これを修正する方法、またはこの問題を回避する方法について何か考えはありますか? これらの非表示のキューイングをブロックし、すぐに使用されなくなる UIElements はありますか?

2013 年 1 月 25 日編集: メモリに保存されているものを具体的に整理する必要があるかもしれないことに気付きました。行オブジェクトは、メモリに保存されない UIElement への参照がないためです (これは良いことです)。Get アクセサーを介してアクセスされる UIElements のみがメモリに残ります。それらへの唯一の参照は PriorityQueue であり、私自身のコードは何もありません。

4

1 に答える 1