Garbage collector test

我与影子孤独终老i 提交于 2019-12-22 08:15:51

问题


I have written a simple .net forms application to test some behaviour of .NET about how it handles memory together with the garbage collector to do the cleaning.

The forms application GUI looks like this:

And the code behind like this:

public partial class Form1 : Form
{
    private readonly IList<byte[]> _btyList = new List<byte[]>();

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        int i = 0;

        while (i < 3)
        {
            byte[] buffer = File.ReadAllBytes(@"C:\PFiles\20131018_nl_metro holland.pdf");
            _btyList.Add(buffer);
            i++;
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        int i = 0;

        while (i < _btyList.Count)
        {
            _btyList[i] = null;
            i++;
        }
    }

    private void button3_Click(object sender, EventArgs e)
    {
        GC.Collect();
    }
}

When I add a couple of byte arrays to the private list of byte arrays it (of course) has effect on the memory usage of the application:

Now when I press the Clear memory button the memory usage will stay the same. I can wait for hours, but it doesn't change. If I press the Garbage collect button (after Clear memory) it will free the memory immediately:

The question is: Why does the garbage collector not work in this case?


回答1:


The garbage collector isn't running because it doesn't need to. If memory is not low, there is no need to collect.

If you have 4GB of memory, 360MB is probably below the collection threshold.

You shouldn't, in general, ever worry or think about when the GC runs, unless you are writing time or memory critical code.

Ref.: Fundamentals of Garbage Collection

Understanding Garbage Collection in .NET

Garbage collection occurs when one of the following conditions is true:

  • The system has low physical memory.

  • The memory that is used by allocated objects on the managed heap surpasses an acceptable threshold. This threshold is continuously adjusted as the process runs.

  • The GC.Collect method is called. In almost all cases, you do not have to call this method, because the garbage collector runs continuously. This method is primarily used for unique situations and testing.




回答2:


Garbage collection is relatively slow and the CLR won't do it every time memory becomes free, only when it needs to. So "freeing" your array doesn't trigger it.

Your experiment has been a complete success: you have learned something about how garbage collection works.




回答3:


Its behaving correctly. Garbage collector run is indeterministic, you can't be sure at what time it will run.

GC will collect memory once it feels need that new memory allocation requires some previous allocated memory to be freed.

From MSDN -

Each time you create a new object, the common language runtime allocates memory for the object from the managed heap. As long as address space is available in the managed heap, the runtime continues to allocate space for new objects. However, memory is not infinite. Eventually the garbage collector must perform a collection in order to free some memory. The garbage collector's optimizing engine determines the best time to perform a collection, based upon the allocations being made. When the garbage collector performs a collection, it checks for objects in the managed heap that are no longer being used by the application and performs the necessary operations to reclaim their memory.




回答4:


The GC runs when a trigger happens. A trigger might be a failing allocation or a low-memory event generated by Windows.

Setting a variable to null is not tracked in any way and is not a trigger.

Your case is a valid case for using GC.Collect because you have knowledge about your deallocation patterns that the GC does not have.



来源:https://stackoverflow.com/questions/19464394/garbage-collector-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!