GC(垃圾回收)可以说是.NET众多机制中最重要的一个,在CLR规范制定之初,所有机制都还在斟酌的时候,垃圾回收已经被确定存在于.NET的框架之中了。
先来看看微软官方给出的解释(.NET Framework 4.6 and 4.5):
在公共语言运行时 (CLR) 中,垃圾回收器用作自动内存管理器。它提供如下优点:
1.使你可以在开发应用程序时不必释放内存。
2.有效分配托管堆上的对象。
3.回收不再使用的对象,清除它们的内存,并保留内存以用于将来分配。托管对象会自动获取干净的内容来开始,因此,它们的构造函数不必 对每个数据字段进行初始化。
4.通过确保对象不能使用另一个对象的内容来提供内存安全。
下面根据自己的理解总结了下面几个问题来回顾一下垃圾回收的机制:
1.什么样的对象会被回收?
答:没有变量引用的对象 :当垃圾回收器的指针指向托管堆以外的内存空间时,就需要回收内存中的垃圾了。在这 个过程中,垃圾回收器首先假设在托管堆中所有的对象都需要被回收。然后它在托管堆中寻找被根对象引用的对象(根对象就是全局,静态或处于活动中的局部变量 以及寄存器指向的对象),找到后将它们加入一个有效对象的列表中,并在已经搜索过的对象中寻找是否有对象被新加入的有效对象引用。直到垃圾回收器检查完所 有的对象后,就有一份根对象和根对象直接或间接引用了的对象的列表,而其它没有在表中的对象就被从内存中回收。
2.什么时候回收?
答:不确定:当系统具有低的物理内存,程序需要新内存的时候开始执行回收,具体时间并不清楚
3.可以手动回收吗?
答:可以:调用GC.Collect()可以手动调用垃圾回收器。但是不建议使用,因为垃圾回收时会暂停一下(非常短暂),最好让程序自动去GC,除非有特殊情况,比如在运行大型操作之前,为了保证内存够用,先回收一下。
4.垃圾回收一共有几代?什么意思?
答:CLR使用了“代”概念来优化垃圾回收器,代是垃圾回收机制使用的一个逻辑技术,也是一种算法,它把托管堆中的内存分为3个代(截止到.NET Framework4.0有3个代:0、1、2)
第0代:新建对象和从未经过垃圾回收对象的集合
第1代:在第0代收集活动中未回收的对象集合
第2代:在第1和第2代中未回收的对象集合, 即垃圾收集器最高只支持到第2代, 如果某个对象在第2代的回收活动中留下来,它仍呆在第2代的内存中。
class Program { static void Main(string[] args) { /* M1(); Console.WriteLine("ok"); Console.ReadKey(); //运行完后,x是不是垃圾回收了? //不是,值类型变量x是存放在栈中,不需要被垃圾,完毕后直接出栈 */ Person p = new Person(); p.Age = 19; p.Name = "张三"; //当程序执行到写OK时,对象P是否被垃圾回收? 不,此时还在使用中 /* p = null; //此时这个person对象可以被回收 Person p1 = p; //此时不可以被垃圾回收 */ Person[] pp = new Person[10]; pp[0] = p; //依然不能被垃圾回收 Console.WriteLine("ok"); Console.ReadKey(); private static void M1() { int x = 100; x++; Console.WriteLine(x); } class Person { public string Name { get; set; } public int Age { get; set; } } }
垃圾回收的最重要目的是:提高内存的使用率,但是只是内存资源回收,内存资源之外的回收是Dispose()
说点什么
欢迎讨论