C#垃圾回收GC机制

https://www.cnblogs.com/yzl050819/p/6245463.html

可以参考这篇文章的内容

程序员不能控制解构器何时将被执行因为这是由垃圾收集器决定的。垃圾收集器检查不在被应用程序使用的对象。它认为这些条件是符合清楚的并且收回它们的内存。解构器也在程序退出时被调用。当解构器执行时其背后所发生的那一幕是解构器隐式调用对象基类的Object.Finalize方法。因此上述解构器代码被隐含转化成:

protected override void Finalize()  
{  
    try  
    {  
       // Cleaning up .  
    }  
    finally  
    {  
       base.Finalize();  
    }
}

其实就是跟java类似。就是记得调试。或者写测试代码的时候如果是通过Console.WriteLine打印记得,立刻调用Flush刷新Console。避免出现理解上的错误,就是到底这个打印是什么时候输出的。

以下是我的测试代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ceshidemo
{
    class Tid
    {
        public static void printid()
        {
            Console.WriteLine("当前线程id是:"+tid().ToString());
            Console.OpenStandardOutput().Flush();
        }
        public static int tid()
        {
            return Thread.CurrentThread.ManagedThreadId;
        }
    }
    class A
    {
        public A()
        {
            Console.WriteLine("Creating A");
        }
        ~A()
        {
            Console.WriteLine("Destroying A");
        }
    }

    class B : A
    {
        public B()
        {
            Console.WriteLine("Creating B");
        }
        ~B()
        {
            Console.WriteLine("Destroying B");
        }

    }
    class C : B
    {
        public C()
        {
            Console.WriteLine("Creating C");
        }

        ~C()
        {
            Console.WriteLine("Destroying C");
        }
    }

    class classA
    {
        public classA()
        {
            Console.WriteLine("ClassA Init");
        }
        
        ~classA()
        {
            Console.WriteLine("ClassA UnInit");
            Tid.printid();
        }
    }


    class Program
    {
        public static string g_static_string = static_return_string();
        public static string static_return_string()
        {
            Console.WriteLine("这里可以执行 初始化哦 这是program的初始化");
            Tid.printid();
            return "str";
        }

        static void demo002()
        {
            Console.WriteLine("进入 demo002");
            demo001();
            GC.Collect();
            Thread.Sleep(3000);
            Console.OpenStandardOutput().Flush();  
            Console.WriteLine("离开 demo002");
            Console.OpenStandardOutput().Flush();
        }
        static void demo001()
        {
            Console.WriteLine("进入 demo001 进入作用域");
            classA _a;
            _a= new classA();
            Console.WriteLine("离开 demo001 离开作用域");
        }

        static void Main(string[] args)
        {

            Console.WriteLine("Main函数线程  "+Tid.tid());
            Console.ReadLine();
            C c = new C();

            Console.WriteLine("开始调用 调用 demo001 的外面 111 ");
            demo002();
            Console.WriteLine("demo002外面调用已经结束了 ");
            Console.OpenStandardOutput().Flush();
            Console.WriteLine("Press enter to Destroy it");
            Console.ReadLine();
            c = null;
            //防止是io没有刷新遇到的问题。
            Console.WriteLine("at the end of the line ");
            Console.OpenStandardOutput().Flush();
            Console.ReadKey();
        }
    }
}

C#垃圾回收GC机制_第1张图片

 

离开作用域后 new对象就被认定是可以可以删除的了。只是GC机制不会立马删除,除非强制调用GC.collect

调用GC.collect也可以发现析构的线程不一样了,真正的析构classA的线程变成了2。就是说GC.collect是促使进行资源回收。真正的回收是在另一个线程完成的。所以有时候调用GC.collect发现有些对象的析构函数执行不是和调用GC.collect执行部分的代码流程是顺序的也是这个原因,通常会认为collect调用完毕,那些析构函数就完成了,这是错的,但是你在collect后面sleep几秒就看得出顺序,这是因为真正执行析构函数的线程已经得到机会在执行了。

你可能感兴趣的:(C#一点点)