WPF:它会导致内存泄漏吗

本文关键字:内存 泄漏 WPF | 更新日期: 2023-09-27 18:05:07

[编辑]

在静态类myWork中,

public static class myWork()
{
    public static SomeWPFCollectionType myGenerate()
    {
        SomeWPFCollectionType myGenerated=new SomeWPFType();
        List<SomeType> myLists=new List<SomeWPFType>();
        for(int i=0 ; i < someCount ; i++)
        {
            myLists.Add(new SomeType(...););
        }
        myGenerated = SomeTypeToSomeWPFCollection(myGenerated);
        return myGenerated;
    }
}
....
public partial class MainWindow : Window
{
    ...
    private void btn1_Click(...)
    {
        this.someControl.someCollection = myWork.myGenerate();
    }
}
  1. 什么时候清除myLists的内存
  2. 什么时候清除myGenerated的内存

当我第一次调用btn1click时,我就预料到了。但Windows的"任务管理器"报告似乎是内存泄漏,很不礼貌。

-编辑-

我不认为我的代码没有在myLists上发生泄漏。因为,

        ....
        myGenerated.Unloaded += delegate(...)
        {
             //i breaked here and see a value of myList in the Watch window of VS.
             Debug.write(myList.ToString());      
        }
        myGenerated = SomeTypeToSomeWPFCollection(myGenerated);
        return myGenerated;
        ....

当myGenerated被卸载时,但myList仍然有15个项目。

WPF:它会导致内存泄漏吗

垃圾收集器负责释放未使用的先前分配的内存。

}1.清除myLists的内存是什么时候?

当你点击按钮时。这显然没有清除myGenerated的前一个实例。

2.myGenerated的内存清除时间是什么时候?

每次单击按钮时,您的代码都会创建一个myGenerated的新实例。

一旦myLists和myGenerated的变量超出范围,垃圾收集器将随时为它们释放内存。

myLists的作用域仅在静态类中,而myGenerated的作用域要大得多。

此外,单击按钮时,myGenerated的新实例将替换旧实例。这使得旧实例可以自由进行垃圾收集。

因此,在您提供的代码中没有真正的内存泄漏。

我不确定这是否能回答你的问题,但我希望它能有所帮助。

我在您发布的代码中没有发现内存泄漏。任务管理器不是检查内存泄漏的合适工具。垃圾回收器不需要立即释放所有未引用的对象。

如果您确实怀疑内存泄漏,请查看sos.dll进行调试。请参阅:http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx

在第二个代码片段中,委托捕获对新创建和填充的列表的引用,当然会将该列表转储到调试窗口。

简而言之:代码可能还可以,但您必须提高调试技能。

如果它是一个静态列表,那么只生成一次。如果这是动态的,那么这不是正确的解决方案。如果您的目标是将控件绑定到动态内容,则将集合公开为ObservableCollection属性并绑定到它。在您的"内存泄漏"中,直到myGenerate((生成的SomeWPFCollectionType超出范围,它才会被垃圾收集。如果将控件绑定到新的集合,则旧的集合似乎应该被垃圾回收。我认为你的代码有缺陷,但我没有看到"内存泄漏"。

        private List<DocFieldEnum1row> docFieldEnum1rows;
        public List<DocFieldEnum1row> DocFieldEnum1rows 
        { 
            get 
            {
                if (docFieldEnum1rows == null)
                {
                    docFieldEnum1rows = new List<DocFieldEnum1row>();
                    // code to populate list here                
                }
                return docFieldEnum1rows;
            } 
        }