【问题标题】:C# managed memory leakC# 托管内存泄漏
【发布时间】:2016-02-13 12:42:02
【问题描述】:

我有一个简单的课程:

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];
    }

}

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

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

【问题讨论】:

  • 不是 100% 肯定,但大对象往往存在于内存中的空间中,该空间不经常被垃圾收集。此外,GC.Collect() 不会触发垃圾收集,而是指示垃圾收集器应该尽快运行。也许其他人可以对此发表评论。
  • 尝试将 MyClass 继承为 IDisposable 并在使用完后调用 c1.Dispose()。顺便说一句,虽然显式调用垃圾收集器并不是一个很好的做法
  • @User2012384 我不确定IDisposable 在这种情况下是否有用
  • @Micky 刚刚研究了一下,发现有一种方法可以清除使用cc.davelozinski.com/c-sharp/fastest-way-to-clear-collections完成的数组,OP可以尝试在“Dispose”方法中清除数组。
  • @User2012384 很有趣。同意并感谢!

标签: c# garbage-collection heap-memory


【解决方案1】:

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

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

还有一个用于大对象的堆,称为:Large Object Heap (LOH)。欲了解更多信息,请查看:Why Large Object Heap and why do we care?

希望这些信息对您有所帮助。

【讨论】:

  • 你在这里混合了 LOH 和 gen2。
猜你喜欢
  • 2012-01-30
  • 1970-01-01
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
相关资源
最近更新 更多