WPF:是否导致内存泄漏?

时间:2011-08-11 12:36:26

标签: c# memory memory-leaks

[编辑]

在静态类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?
  3. 第一次,我预计当我打电话给btn1_click时。 但Windows的“任务管理器”报告显然是内存泄漏,显而易见。

    -edited -

    我不认为我的代码没有在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个项目。

5 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

  

} 1.记忆清除myLists的时间是什么时候?

单击按钮时。这显然不会清除myGenerated的前一个实例。

  

2.记忆清除myGenerated的时间是什么时候?

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

答案 2 :(得分:0)

一旦这些变量超出范围,垃圾收集器就会释放myLists和myGenerated的内存。

myLists的范围仅在您的静态类中,而myGenerated的范围要大得多。

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

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

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

答案 3 :(得分:0)

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

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

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

简而言之:代码可能没问题,但您必须处理调试技巧。

答案 4 :(得分:0)

如果是静态列表,则只生成一次。如果这是动态的,那么这不是正确的解决方案。如果您的目标是将控件绑定到动态内容,则将集合公开为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;
            } 
        }
相关问题