DotNet 垃圾回收
DotNet中垃圾回收
1>.只能回收内存资源,托管堆中资源(不可回收数据库连接,文件句柄,端口等).
2>.没有变量引用的对象,才会被垃圾回收(但是什么时候回收不能确定)
4>.手动调用垃圾回收。一般不手动回收,由系统自动调用。(垃圾回收一系列算法,需要移动对象等等,这时为了达到目的,需要暂时应用程序的已处理,频繁的垃圾回收会影响系统性能):GC.Collect();
5>.垃圾回收‘代’的机制 mark-and-compact (标记与压缩)
‘代’机制分为三代:0代,1代,2代。 最开始GC将所有的对象都放在0代中,某一时刻,GC要进行垃圾回收,它会释放0代中的所有未 被引用的内存,GC将还有应用的对象放到1代中,如此反复,如果1代中内存满了,GC会释放1代中的未被引用的资源,再将有引用大的
资源放到2代中,如此反复,如果2代中的内存满了就释放2代中的内存,如此反复,如果2代中不能释放内存了,程序会抛出‘内存溢 出’异常
注意:0代是当需要时释放资源,1,2代是当内存满了时释放资源。
代机制的mark-and-compact(标记与压缩)是指:垃圾回收后,未必回收的对象(还有引用)会做上标记,移到下一层,除最后一代2代。
再将对象压缩,依次存放
垃圾回收采用了代的概念,避免了每次垃圾回收都遍历所有的对象,减少了垃圾回收的时间。第0代垃圾回收的频率最高,1代次之,2代再次
6>.继承自IDisposable接口的Dispose()方法,可以释放除内存之外的其他资源
class Person:IDisposable
{
public int Age
{
get;
set;
}
public void Dispose()
{
释放除内存外的资源
}
}
7>.垃圾回收--终结函数(C++中析构函数)
~类名(){
访问外部资源一般用Dispose()方法(继承 IDisposable接口)
如果有Dispose()方法释放了内存就不需要调用终结函数了 Finalize()方法,所以就通过GC.SuppressFinalize(this); 告诉程序不调用 Finalize()方法了
};
析构函数实际上就是掉用了Finalize()方法。
8>.弱引用:
特点:被弱引用引用的对象当没有其他的引用的时候可以被垃圾回收机制回收,如果此对象还没有被垃圾回收机制回收,那么他就可以再
次引用。
2>.若引用一般用在创建时比较耗时的对象
实例:
class Pargram
{
static void main()
{
Person p=new Person();
p.age=12;
WeakReference wr=new WeakReference(p);
p=null;
//如果手动释放 wr就不能得到p对象
GC.Collect();
object obj=wr.Target;
if(obj!=null)
{
Console.WriteLine(p.age);
}else
{
Console.WriteLine("此对象资源以被释放");
}
}
}
class Person
{
private int age;
public int Age
{
get{return age;}
set{this.age=value;}
}
}