zoukankan      html  css  js  c++  java
  • CLRCore(CLR核心机制)

    JIT--第一次--标记已--存根--调用--查找存根--执行机器码

    C#和CIL的关系:

     C#和N#都是CIL实现,但是彼此不能互通:

     C#和N#公开不分满足规范,我们才能互通

     CLS就是描述多语言互通的规范

    内存分配:线程栈

      堆Heap:

        一个程序运行时,该进程存放引用类型变量的一块内存,全局唯一!只有一个堆

      栈Stack:

        数据结构,先进后出,线程栈,一个线程存放变量的内存(一个线程有一个)

      值类型分配在栈上,比如结构、枚举、int等

      引用类型分配在堆上,比如类、接口、委托等

    引用类型

      1、调用new的时候,就会去栈上开辟内存,创建实例。这就是为什么在构造函数中跨域使用this

      2、把实例的引用传递给构造函数

      3、执行构造函数

      4、返回引用

    装箱拆箱

    int i=3;
    obect obj=i;//装箱
    int k=(int)obj;//拆箱

    引用类型在哪里?值类型在哪里?

      值类型的值,会随着对象的位置存储。引用类型的值,一定在堆里面。值类型的长度是确定的,引用类型的长度是不确定的,只有堆才能放各种值。

      下面有一个例子:

    public class MyTest
    {
        private int x;
        public MyTest(int n)
        {
            this.x=n;
        }
    }
    MyTest t=new MyTest(3);//引用类型

      那么,t.x  这个3,是存放在哪里呢?是堆上还是栈上?

        ===.》出现在堆里面,因为值类型的属性,会随着对象的位置存储

     public struct ValuePoint// : System.ValueType  结构不能有父类,因为隐式继承了ValueType
     {
         public int x;
         public ValuePoint(int x)
         {
             this.x = x;
             this.Text = "1234";
         }
    
         public string Text;//堆还是栈?
     }

      struct是值类型,但是里面的Text,是存放在堆还是栈?答案是,对立面,因为引用类型的值,一定出现在堆里面。

    string字符串内存分配

    string student = "bingle1";
    string student2 = student;
    
    Console.WriteLine(student);//bingle1
    Console.WriteLine(student2);//bingle1
    
    student2 = "bingle2";//=new string(APP);
    Console.WriteLine(student);//bingle1
    Console.WriteLine(student2);//bingle2
    Console.ReadLine();
    string student = "bingle1";
    string student2 = "bingle2";//共享
    student2 = "bingle1";
    
    Console.WriteLine(object.ReferenceEquals(student, student2));//true

    为什么是true?因为同一个变量,享元分配内存。为什么享元?节约内存。

    student2 = "binglebingle";//等于重新开辟一块内存叫“binglebingle”  new String("binglebingle")
    Console.WriteLine(student);//bingle1

    还是bingle1,为什么?因为字符串的不可变性。为什么字符串不可以变,开辟新内存不浪费吗?因为在堆上是连续拜访的,如果有变化,会导致其他变量全部移动,成本太高,还不如重新new一个。

    string student3 = string.Format("bing{0}", "le");
    Console.WriteLine(object.ReferenceEquals(student, student3));//false

    为什么是false?没有享元。分配地址,然后计算,才知道是"bingle"。

     string student4 = "bing" + "le";
     Console.WriteLine(object.ReferenceEquals(student, student4));//true
     //true  编译器优化了,直接就是bingle
    string halfStudent = "le";
    string student5= "bing" + halfStudent;
    Console.WriteLine(object.ReferenceEquals(student, student5));
    //false 也是先内存,再计算

    东西放在站上速度快,但是值类型是不能继承的,长度也有限。

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

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

        托管资源+引用类型。线程栈的是不需要垃圾回收的,用完立马就回收了。

      2、托管资源和非托管资源

        托管资源的就是CLR控制的,new的对象、string字符串。非托管就不是CLR控制的,数据库连接、文件流、句柄、打印机连接。using(SqlConnection)//被C#封装了管道了那个非托管的数据库连接资源。只要手动释放的,都是非托管的。

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

        对象访问不到了,那就可以被回收了。程序----入口----去找对象---建立对象图----访问不到的就是垃圾,就可以回收了。

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

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

       5、什么时候执行GC?

        a、new对象的时候----临界点

        b、GC.Collection(),这个方法会强制GC

        c、程序退出时会GC

        a="123"

        a=null

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

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

      6、GC的过程是怎么样的?

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

        清理内存分两种情况:

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

          b、把对象转到一个单独的队列,会有一个析构函数专门做这个。通常在析构函数内部是用来做非托管资源释放,因为CLR肯定调用,所以避免使用者忘记的气矿。

      7、垃圾回收策略

         对象分代:3代

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

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

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

        垃圾回收时,优先回收0代,提升小路,最多也最容器释放。0代不够,找1代,1代不够找2代,再不够就不用了。。。代的数值越大,越难回收。

        大对象堆:一是内存移动大对象;二是0代空间问题。80000字节就叫大对象,没有分代,直接都是2代。

        那么,静态资源在程序退出的时候,会GC吗?答案是,会的。(其实回收的不是变量,是某个对象所占据的内存,如果存在一个对象,指向它的引用变量的数量为0,那个GC会择机回收它占据的内存。应用程序域卸载的时候回收静态变量。)

    析构函数:被动清理;Dispose:主动清理

        

     public class StandardDispose : IDisposable
     {
         //演示创建一个非托管资源
         private string _UnmanageResource = "未被托管的资源";
         //演示创建一个托管资源
         private string _ManageResource = "托管的资源";
    
    
         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");
             }
             //
         }
  • 相关阅读:
    解决小问题VC2008通过ADO连接ACCESS (转)
    给zblog站点备份和搬家
    vc中自定义编译时的输出消息 .
    更改MFC 对话框控件的tab顺序
    dotnetbar 添加到工具栏方法
    关于完成端口IOCP异步接收连接函数AcceptEx注意事项 (转)
    中英文url解码vc++源程序
    c#关于网页内容抓取,简单爬虫的实现。(包括动态,静态的)
    图解使用Broadcom Advanced Control Suite 2设置Broadcom单网卡跨多VLAN(转)
    windbg调试环境变量记录
  • 原文地址:https://www.cnblogs.com/taotaozhuanyong/p/11564117.html
Copyright © 2011-2022 走看看