1

I have a simple class :

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

}

When I click button1, The managed memory (Bytes in all heaps counter, perfmon) is growing up (as expected). But when I click button2, I expect that managed memory should be released. But it also grow up !! And only after second button2 click, the memory released. What is an explanation for this behavior??

And why, when application just started, the "Bytes in all heaps counter" is 0? I think it should be more than 0 .There are some objects already allocated on managed heap. MainWindow for example.. Thank you, all

Matvey
  • 163
  • 2
  • 10
  • Not 100% sure, but large objects tend to live in a space in memory which is not garbage collected frequently. Also, `GC.Collect()` does not trigger garbage collection, but rather indicates the garbage collector that it should run sooner. Maybe others can comment on this. – npinti Nov 12 '15 at 08:37
  • Try inheriting MyClass as IDisposable and call c1.Dispose() after you finish using. By the way, explicitly calling Garbage collector isn't a very good practice though – User2012384 Nov 12 '15 at 08:38
  • @User2012384 I'm not sure`IDisposable` would be useful in this case –  Nov 12 '15 at 08:39
  • 1
    @Micky Just now took a research and found out there's a way to clear the array that's finished using http://cc.davelozinski.com/c-sharp/fastest-way-to-clear-collections, OP can Try clearing the array in the "Dispose" method. – User2012384 Nov 12 '15 at 08:40
  • @User2012384 Interesting. Agreed and thanks! –  Nov 12 '15 at 08:45
  • You just found out that perfmon is not the right (accurate) way to monitor memory. There is no leak here. – H H Nov 16 '15 at 17:46

1 Answers1

0

If you call GC.Collect, no memory will be freed. The object without a root will only stored in a queue to be freed. Read some thing about: GC.WaitForPendingFinalizers Method ()

Also notice, that objects with the size of more than ~82MB, will automatically stored in gen2, so they will not be collected automatically as far as i know.

There is also a heap for large objects, called: Large Object Heap (LOH). For more information take a look at: Why Large Object Heap and why do we care?

Hope this informations helps.

Community
  • 1
  • 1
BendEg
  • 20,098
  • 17
  • 57
  • 131