2

Windows (8.1) Universal プロジェクトでメモリ リークが発生しました。私のプロジェクトは非常に大きいので、メモリ リークを模倣することだけを目的とした小さなサンプル プロジェクトを作成しました。このメモリリークを解決するために多くのことを試みましたが、役に立ちませんでした。

状況は次のとおりです。アプリにはリストが含まれており、ボタンがクリックされるとデータがリストに追加され、2 番目のボタンがクリックされるとリストがクリアされます。アイテムがリストに追加されると、メモリ使用量が増えると予想されますが、実際に発生します。ただし、リストをクリアすると、メモリ使用量がアイテムを追加する前のレベルまで低下することが予想されます。これは起こりません。代わりに、メモリ使用量は、アイテムを追加する前よりも約 1 MB (リストに追加されたアイテムの数によって明らかに異なります) 増加しています。

この問題を解決するのを手伝ってもらえますか?

リストに項目を追加するコードは次のとおりです。

    private Custom_Observable_List leaking_items_list = new Custom_Observable_List();
    private void AddItemsToList()
    {
        if (RESET_LIST_BEFORE_ADDING)
        {
            ClearItemsList();
        }

        if (ItemList.ItemsSource == null)
        {
            ItemList.ItemsSource = leaking_items_list;
        }

        for (int i = 0; i < AMOUNT_OF_ITEMS_TO_ADD; i++)
        {
            leaking_items_list.Add(new ObjectClass() { Content = ITEM_CONTENT + number_of_items_added });
            number_of_items_added++;
        }
    }

ここで、ItemList は XAML の ListView です。ItemSource が設定されていない場合でも、メモリ リークが発生します。リークは、ListView よりも ObservableCollection の方が多いと思われます。

リストをクリアするコード:

    private void ClearItemsList()
    {
        if (leaking_items_list.Count > 0)
        {
            leaking_items_list.Clear();
        }
    }

Custom_Observable_List クラス:

class Custom_Observable_List : ObservableCollection<ObjectClass>
{
    public Custom_Observable_List()
    {
    }

    public Custom_Observable_List(IEnumerable<ObjectClass> collection) : base(collection)
    {
    }
}

ガベージ コレクションが実際にすべてをクリーンアップできるように、追加されたオブジェクトへの参照を保持しないように、ここに何かを追加する必要があると思います。しかし、何を追加すればよいかわかりません。

リストに追加されるオブジェクトのクラスは次のとおりです。

class ObjectClass : INotifyPropertyChanged
{
    private string content = string.Empty;

    public string Content
    {
        get { return content; }
        set
        {
            if (content != value)
            {
                content = value;
                NotifyPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

リストに文字列を追加するだけでも試してみましたが、メモリリークも発生しました。INotifyPropertyChanged を実装する必要があることをどこかで読んだので、このクラスを作成しました。

プロジェクト全体は次の場所にあります。

Memory_Leak_Test.zip

Visual Studio 2015 とその診断ツールを使用してテストしました。メモリ使用量が多すぎるため、数回追加してクリアするとプログラムがクラッシュすることを確認しました。

4

0 に答える 0