C#垃圾回收问题和分析

Posted by JohnWayne on April 24, 2022

结合网上的案例,通过调试引发新的问题进行思考


以下测试代码基于这篇文章的基础上进行了修改 https://www.cnblogs.com/mq0036/p/3707257.html

一段测试代码

using System;

namespace GCCollectIntExample
{
    public class CountObject
    {
        public static int Count = 0;

        public CountObject()
            {
                Count++;
            }

            ~CountObject()
            {
                Count--;
            }
        
    }
    class MyGCCollectClass
    {

        static void Main()
        {
            //GC.Collect();
            //GC.WaitForPendingFinalizers();

            //Console.WriteLine(CountObject.Count);
            //Console.WriteLine("创建大量实例前,清理手动GC=>Total Memory: {0}", GC.GetTotalMemory(false));

            Console.WriteLine("创建大量实例前=>Total Memory: {0}", GC.GetTotalMemory(false));

            CountObject myGCCol;
            for (int i = 0; i < 100; i++)
            {
                myGCCol = new CountObject();
                myGCCol = null;
            }
            Console.WriteLine(CountObject.Count);
            Console.WriteLine("创建大量实例后=>Total Memory: {0}", GC.GetTotalMemory(false));
            
            GC.Collect();
            GC.WaitForPendingFinalizers();

            Console.WriteLine(CountObject.Count);
            Console.WriteLine("手动GC后=>Total Memory: {0}", GC.GetTotalMemory(false));

            GC.Collect();
            GC.WaitForPendingFinalizers();

            Console.WriteLine(CountObject.Count);
            Console.WriteLine("再次手动GC后=>Total Memory: {0}", GC.GetTotalMemory(false));
            
            Console.ReadKey();
        }

        
    }
}
>>>
创建大量实例前=>Total Memory: 152680
100
创建大量实例后=>Total Memory: 160872
1
手动GC=>Total Memory: 77080
1
再次手动GC=>Total Memory: 74704

第一个问题:为什么第二次手动GC会再次清理一些空间,第三次及之后GC无变化

网上的答案:https://qa.icopy.site/questions/3829928/under-what-circumstances-we-need-to-call-gc-collect-twice?noredirect=1

第二个问题,如果在创建大量实例前,清理手动GC(解注释上面那段代码),会得到这样的结果

>>>
0
创建大量实例前,清理手动GC=>Total Memory: 69864
创建大量实例前=>Total Memory: 69864
100
创建大量实例后=>Total Memory: 69864
1
手动GC=>Total Memory: 77192
1
再次手动GC=>Total Memory: 74816

再次手动GC清理后为什么内存仍然比创建大量实例前的内存还要大?

作者 [张巍]

2022 年 04月 24日