C#托管内存泄漏

C#托管内存泄漏,c#,garbage-collection,heap-memory,C#,Garbage Collection,Heap Memory,我有一个简单的课程: public partial class MainWindow : Window { MyClass c1, c2, c3; public MainWindow() { InitializeComponent(); } private void Button1_Click(object sender, RoutedEventArgs e) { c1 = new MyClass();

我有一个简单的课程:

public partial class MainWindow : Window
{
    MyClass c1, c2, c3;
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button1_Click(object sender, RoutedEventArgs e)
    {
        c1 = new MyClass();
        c2 = new MyClass();
        c3 = new MyClass();
    }

    private void Button2_Click(object sender, RoutedEventArgs e)
    {
        c1 = null;
        c2 = null;
        c3 = null;
        GC.Collect();
    }
}

class MyClass
{
    String[] s;
    public MyClass()
    {
        s= new String[1000000];
    }

}
当我单击按钮1时,托管内存(所有堆计数器中的字节,perfmon)正在增长(如预期的那样)。但当我单击按钮2时,我希望应该释放托管内存。但它也长大了!!只有在第二个按钮2点击后,内存才会释放。 这种行为的解释是什么

为什么应用程序刚启动时,“所有堆中的字节计数器”为0? 我认为应该大于0。托管堆上已经分配了一些对象。例如,主窗口。。
谢谢大家

如果您调用
GC.Collect
,将不会释放任何内存。没有根的对象将只存储在要释放的队列中。读一些关于:

另外请注意,大小超过
~82MB
的对象将自动存储在
gen2
中,因此据我所知,它们不会自动收集

还有一个用于大型对象的堆,称为:大型对象堆(LOH)。有关更多信息,请参阅:


希望这些信息能有所帮助。

不是100%确定,但大型对象往往位于内存中不经常进行垃圾收集的空间中。另外,
GC.Collect()
不会触发垃圾回收,而是指示垃圾回收器应该更快地运行。也许其他人可以对此发表评论。请尝试将MyClass继承为IDisposable,并在完成使用后调用c1.Dispose()。顺便说一下,显式调用垃圾收集器不是一个很好的实践though@User2012384我不确定
IDisposable
在这方面是否有用case@Micky刚才进行了一项研究,发现有一种方法可以清除已完成使用的数组,OP可以尝试使用“Dispose”方法清除数组。@User2012384有趣。同意,谢谢!你把LOH和gen2混在一起了。