2020年9月23日星期三

.NET中的GC垃圾回收

本章将和大家分享.NET中的GC垃圾回收。

托管堆垃圾回收--CLR提供GC。

1、什么样的对象需要垃圾回收?

  托管资源+引用类型

  托管资源和非托管资源:

    托管的就是CLR控制的,例如:new的对象、string字符串、变量等;

    非托管不是CLR能控制的,例如:数据库连接、文件流、句柄、打印机连接等;

    using(SqlConnection)--被C#封装了用来管理那个非托管的数据库连接资源;

    只要是需要手动释放的,都是非托管的。

2、哪些对象的内存,能被GC回收?

  对象访问不到了,那就可以被回收了

  程序--入口--去找对象--建立对象图--访问不到的就是垃圾。

3、对象是如何分配在堆上?

  连续分配在堆上面,每次分配就先检查空间够不够。

4、什么时候执行GC?

  a、new对象时--临界点

  b、GC.Collect 强制GC

  c、程序退出时会GC

  a="123"

  a=null

  GC.Collect  可以GC,但是频繁GC是不好的,GC是全局的。

  如果项目中有6个小时才运行new一次,什么时候GC? 这6个小时都不GC,可以手动GC。

5、GC的过程是怎么样的呢?

  N个对象--全部对象标记为垃圾--入口开始遍历--访问到的就标记可以访问(+1)--遍历完就清理内存--产生不连续内存--压缩--地址移动--修改变量指向--所以会全局阻塞。

  清理内存分2种情况:

    a、无析构函数,直接清理内存。

    b、把对象转移到一个单独的队列,会有个析构器线程专门做这个(清理慢一些)通常在析构函数内部是用来做非托管资源释放,因为CLR肯定会调用,可以避免使用者忘记的情况。

6、垃圾回收策略

  对象分代:3代

  0代:第一次分配到堆,就是0代

  1代:经历了一次GC,依然还在的

  2代:经历了两次或以上GC,依然还在的

  垃圾回收时,优先回收0代,提升效率,最多也最容易释放。

  0代不够---找1代---1代不够才找2代--再不够就不够了。。

  大对象堆,没有分代,直接都是2代,80000字节以上就叫大对象。

  大对象堆没有分代这主要有2个原因:一是内存移动时如果是大对象则很耗资源;二是0代空间问题;

7、标准Dispose模式

using System;namespace MyGC{ /// <summary> /// 标准Dispose模式 ///  /// 析构函数:被动清理 /// Dispose:主动清理 /// </summary> public class StandardDispose : IDisposable {  /// <summary>  /// 演示创建一个非托管资源  /// </summary>  private string _unmanageResource = "未被托管的资源";  /// <summary>  /// 演示创建一个托管资源  /// </summary>  private string _manageResource = "托管的资源";  /// <summary>  /// 是否已释放  /// </summary>  private bool _disposed = false;  /// <summary>  /// 实现IDisposable中的Dispose方法  /// </summary>  public void Dispose()  {   this.Dispose(true); //必须为true   GC.SuppressFinalize(this); //通知垃圾回收机制不再调用终结器(析构器)(析构函数)  }  /// <summary>  /// 不是必要的,提供一个Close方法仅仅是为了更符合其他语言(如C++)的规范  /// </summary>  public void Close()  {   this.Dispose();  }  /// <summary>  /// 析构函数  /// 必须,以备程序员忘记了显式调用Dispose方法  /// </summary>  ~StandardDispose()  {   //必须为false   this.Dispose(false);  }  /// <summary>  /// 非密封类修饰用protected virtual  /// 密封类修饰用private  /// </summary>  /// <param name="disposing">是否清理托管资源</param>  protected virtual void Dispose(bool disposing)  {   if (this._disposed) //避免已经被释放的抛异常   {    return;   }   if (disposing)   {    //清理托管资源    if (this._manageResource != null)    {     //Dispose     this._manageResource = null;    }   }   //清理非托管资源   if (this._unmanageResource != null)   {    //Dispose conn.Dispose()    this._unmanageResource = null;   }   //让类型知道自己已经被释放   this._disposed = true;  }  public void PublicMethod()  {   if (this._disposed)   {    throw new ObjectDisposedException("StandardDispose", "StandardDispose is disposed");   }  } }}

 

此文由博主精心撰写转载请保留此原文链接:https://www.cnblogs.com/xyh9039/p/13715181.html

版权声明:如有雷同纯属巧合,如有侵权请及时联系本人修改,谢谢!!!

原文转载:http://www.shaoqun.com/a/477540.html

crowd:https://www.ikjzd.com/w/880

五洲会:https://www.ikjzd.com/w/1068

转运四方:https://www.ikjzd.com/w/1342


本章将和大家分享.NET中的GC垃圾回收。托管堆垃圾回收--CLR提供GC。1、什么样的对象需要垃圾回收?  托管资源+引用类型  托管资源和非托管资源:    托管的就是CLR控制的,例如:new的对象、string字符串、变量等;    非托管不是CLR能控制的,例如:数据库连接、文件流、句柄、打印机连接等;    using(SqlConnection)--被C#封装了用来管理那个非托管的数
杨帆:https://www.ikjzd.com/w/1648
extra:https://www.ikjzd.com/w/1736
猛降60%!PB花费成交比就是这么任性!:https://www.ikjzd.com/home/102592
出口跨境电商丨东南亚卖家要做好哪些节假日营销:https://www.ikjzd.com/home/18179
"中东亚马逊Souq.com"要在沙特阿拉伯开设亚马逊全球商店啦!:https://www.ikjzd.com/home/6547

没有评论:

发表评论