C#GC垃圾回收和析构函数和IDisposable的使用

一,什么是GC缓存

1,GC是垃圾回收器,通常来讲系统会自动检测不会使用的对象或变量进行内存的释放,不须要手动调用,用Collect()就是强制进行垃圾回收,使内存获得及时的释放,让程序效率更高.函数

2,GC:只负责回收托管对象,不负责回收非托管对象。this

那什么是垃圾? 垃圾是彻底访问不到的东西了,就是当前程序执行后该对象或值没有被引用spa

以下图:线程

代码以下:code

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

namespace TestDemo
{
    public class TestDemo
    {
        private static Test t = new Test()//静态的不可能被回收   静态持有的引用也不会被回收
        {
            Id = 123,
            Name = "Test"
        };
        public static void show()
        {
            ///{}这个括号是代码分块的意思,两个块之间是不影响的,第一块执行完后,通常来讲就是会被主动GC释放
            ///而这里obj没有被释放的缘由是由于静态遍历对obj这个引用类型变量的使用
            {
                object obj= new { Name = 1 };
                t.obj = obj;
                int i = 3;//都会被GC
                TestDemo testDemo = new TestDemo();//都会被GC
            }
            {
                GC.Collect();//主动GC
            }
        }
    }

    public class Test
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public object obj { get; set; }
    }
}

总结:程序执行完会回收垃圾,这个obj还在静态的t使用,因此没有被释放对象

那GC怎么回收呢?
1,new的时候发现内存不够 就去遍历全部堆的对象,标记访问不到,而后启动一个线程来清理内存
2,清除标记了的对象,其余挪动,而后整齐摆放,因此这个时候所有线程中止,不容许操做内存
3,内存不够的是指一级对象的内存,有个临界值,也不是所有的堆的大小blog

GC回收执行的过程:
1, 首次GC前 所有对象都是0级
2, 第一次GC后,还保留的对象叫1级
3, 回收先找0级对象,若是空间还不够,再去找1级对象,这以后,还存在的对象就变成2级
4, 0级不够,1级也不够,2级还不够,那就内存溢出了
5,越是最近分配的,越是会被回收 好比for循环建立对象内存

大对象和正常的对象缓存的地址是不同的。
大对象策略:若是大于某个值的对象85k,单独管理,用的是链表(碎片),避免频繁的内存移动资源

二,析构函数和IDisposable的区别?

~Class() 析构函数: 主要是用来释放非托管资源,等着GC的时候去把非托管资源释放掉 系统自动执行
GC回收的时候,CLR必定调用的,可是可能有延迟(释放对象不知道要多久呢)

Dispose() :也是释放非托管资源的,主动释放,方法自己是没有意义的,咱们须要在方法里面实现对资源的释放
GC不会调用,而是用对象时,使用者主动调用这个方法,去释放非托管资源,
而不是说对象释放的时候,会去自动调用Dispose方法,而后在用完对象时,咱们主动去执行dispose方法,固然能够是using的快捷方式

以下代码:

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

namespace TestDemo
{
    public class TestDemoThree
    {
        public static void show()
        {
            {
                for (int i = 0; i < 2; i++)
                {
                    TestThree @class = new TestThree()
                    {
                        Id = i,
                        Name = "TestThree"
                    };
                }
            }
            {
                GC.Collect(); //主动GC的时候,CLR必定调用的析构函数
            }
            {
                ///using 这个会去调用调用的dispose,至关于try后的finally
                using (TestThree TestThree = new TestThree()
                {
                    Id = 1,
                    Name = "444"
                })

                    try
                    {
                        //using至关于
                    }
                    finally
                    {
                        //调用的dispose()
                    }
            }
        }

        public class TestThree : IDisposable
        {
            public int Id { get; set; }
            public string Name { get; set; }
            ~TestThree()
            {
                Console.WriteLine($"执行{this.GetType().Name}~TestThreeDispose");
            }
            public void Dispose()
            {
                Console.WriteLine($"执行{this.GetType().Name}Dispose");
            }
        }
    }
}

主动执行GC执行结果

 using执行结果

相关文章
相关标签/搜索