.NET垃圾回收机制

时间:2022-10-08 00:01:51

     GC是垃圾收集器(Garbage Collection)。程序员不用担心内存管理,因为垃圾收集器会自动进行管理。GC只能处理托管内存资源的释放,对于非托管资源(例如:文件句柄,网络端口等)则不能使用GC进行回收,必须由程序员手工回收,一个例子就是FileStream或者SqlConnection需要程序员调用Dispose进行资源的回收。

    要请求垃圾收集,可以调用下面的方法:GC.Collect()一般不需要手动调用GC.Collect()。当一个对象没有任何变量指向(不再能使用)的时候就可以被回收了。但是, 除非明确知道必须要进行垃圾回收才用这个,否则不用这个。(不要随便调,否则会影响性能)

    为什么频繁调用GC.Collect()会使程序执行变慢:

    调用时候会暂停所有程序的执行(只要垃圾回收都要暂停,原因是将内存重新排列):要进行比较大的操作,并且操作中间一定不能暂停,此时可以调用使内存够用。

   

    垃圾回收机制是以代的方式回收的

垃圾回收共分为3代:0代,第1代,第20代垃圾回收的频率最高;第2代回收频率最低object  o=new byte[85000];>=85000字节的对象被视为大对象,直接分配在第二代,Gc.GetGeneration(o),不要为短时间使用的对象创建大对象,否则频繁收回第二代。

    

     当一个对象没有变量引用的时候,这时候就可以被垃圾回收了,但是接下来如果要是在想用该对象的话也是不可能的,因为即便还没有垃圾回收,但是这个对象已经无法引用了(虽然堆在内存中,但是找不到对象了)。这时,当一个对象没有任何变量引用时,这时候我们可以使用WeakRegerence(弱引用)来保持这个对象的“引用”,这时虽然对该对象“弱引用”了,。但是这个对象时仍然可以被垃圾回收的,如果爱在下次使用这个对象的时候,该对象还没有被垃圾回收,则可以通过弱引用直接找到该对象,然后继续使用,如果已经被垃圾回收了,则需要重新创建这个对象。

    

   通过代码来实现:

        Person p=new Person();

        p.Name="yzk";

        p.Age=18;

        P.Email="";

 

   //弱引用

       WeakReference  wkReference=new WeakReference(p);

       P=null;

    假设某个时间段的时候又要使用这个对象了。

    Object  0=wkReference.Target;

    If(o!=null)

    {

       Person p=o  as person;

   
     }

      一个对象只有一个弱引用

     判断对象是否还活着:

     If(o!=null&&wkReference.IsAlive)如果它还活着,并且不为null,这样还会安全些。

     最好不要这样写:

     If(wkReference.Target!=null)

    {

        Object o=wkReference.Target;
    }

     这是因为如果你不等于Null了,此时又赋给o的又没准为Null了。

   

    在对string进行大量拼接的时候 中间拼接如果是字符串常量的话是不会对旧的字符串进行垃圾回收的,如果是变量则是可以的

 

 

 

引用类型的作用域并不是当作用域超出之后就释放掉,垃圾回收只能回收托管中的内存资源。不回收其它资源(数据库连接,文件句柄,网络端口等)

当对象没有变量引用时,才可以被回收。具体什么时候被回收是不确定。

垃圾回收指的是堆中的对象,不是变量

 

 

GC.Collect();除非明确知道必须要进行垃圾回收才用这个,否则不用这个。(不要随便调,否则会影响性能)

第一:为什么频繁调用GC.Collect()会使程序执行变慢:

调的时候会暂停所有程序的执行(只要垃圾回收都要暂停,原因是将内存重新排列)

什么情况下必须调用:要进行比较大的操作,并且操作中间一定不能暂停,此时可以调用使内存够用。

.

 

垃圾回收是以代的方式回收的

Gc.MaxGeneration   就可以最大的提高他的性能

3代:

0代,第1代,第2

0代垃圾回收的频率最高;第2代回收频率最低

Outofmemary异常,内存不够

当内存不够的话会自动进行扩大,否则就报异常Outofmemary.

只是在操作系统分配给程序的内存中回收和分配

 

.net中垃圾回收机制:mark---and---compact(标记和压缩),一开始假设所有对象都是垃圾。除了内存资源外的其它资源怎么办?或者Dispose()

大对象:object  o=new byte[85000];>=85000字节的对象被视为大对象,直接分配在第二代,Gc.GetGeneration(o),不要为短时间使用的对象创建大对象,否则频繁收回第二代。

 

 

Dispose方法的作用就是回收一些非托管的资源。

例如:FileStream  stream;

      stream.Dispose();

让一个类继承Idispose接口,则可以实现Person  p=new Person();p就可以Dispose

弱引用:如果一个对象刚刚进行垃圾回收后。

弱引只是保持一个联系。

弱引用也可以被垃圾回收。

弱引用的意思是:当一个对象没有变量引用的时候,这时候就可以被垃圾回收了,但是接下来如果要是在想用该对象的话也是不可能的,因为即便还没有垃圾回收,但是这个对象已经无法引用了(虽然堆在内存中,但是找不到对象了)。这时,当一个对象没有任何变量引用时,这时候我们可以使用WeakRegerence(弱引用)来保持这个对象的“引用”,这时虽然对该对象“弱引用”了,。但是这个对象时仍然可以被垃圾回收的,如果爱在下次使用这个对象的时候,该对象还没有被垃圾回收,则可以通过弱引用直接找到该对象,然后继续使用,如果已经被垃圾回收了,则需要重新创建这个对象。

通过代码来实现:

Person p=new Person();

p.Name="yzk";

p.Age=18;

P.Email="";

 

//弱引用

WeakReference  wkReference=new WeakReference(p);

P=null;

假设某个时间段的时候又要使用这个对象了。

Object  0=wkReference.Target;

If(o!=null)

{

  Person p=o  as person;

   
}

一个对象只有一个弱引用

判断对象是否还活着:

If(o!=null&&wkReference.IsAlive)如果它还活着,并且不为null,这样还会安全些。

最好不要这样写:

If(wkReference.Target!=null)

{

   Object o=wkReference.Target;
}

这是因为如果你不等于Null了,此时又赋给o的又没准为Null了。

 

在对string进行大量拼接的时候,中间不是对旧的string对象进行了垃圾回收?

答案:中间拼接如果是字符串常量的话是不会的,如果是变量则是可以的