C#.Net学习笔记——CLR核心机制

这篇具有很好参考价值的文章主要介绍了C#.Net学习笔记——CLR核心机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、CLR基本介绍

(1)C(Common) L(Language) R(Runtime) IL的运行环境

(2)从下图可以看到,我们的计算机会先把我们写的语言,编写成IL语言,再给计算机去读取。为什么我们不直接把我们的语言编写成计算机能够读取的?主要是考虑到我们计算机的不同,比如32位和64位,他们接收到计算机指令都是不一样的。甚至在不同的操作环境下得出的结果也是不一样的。因此,我们就需要有一个中间语言ILCLR(通用语言进行时)就是IL的运行环境。

(3)metadata清单数据,里面是描述了dll或者exe内有什么东西,依赖了什么东西。

(4)Exe文件的运行。实际上我们的exe文件可以运行,都是由CLR完成的,它为我们加载exe,检查metadata清单和IL。最后JIT(运行时编译)会交给计算机去执行。所以说CLR本质上可以说是一个IL的运行环境。

(5)编译器只要满足CLS规范,编译出来的东西就可以转换成IL语法

(6)使用CLR需要安装.Net Framework

C#.Net学习笔记——CLR核心机制,c#,.net,学习

二、堆栈内存分配

(1)基本介绍

什么内存?        程序运行时,进程占有的内存

谁来分配?        CLR来分配

1、值类型:struct  枚举

2、引用类型:class  接口  委托

线程栈:栈-stack 先进后出的数据结构,随着线程而分配的,默认执行方法分配1M内存

对象堆:内存,进程中独立画出来的一块内存,有一些对象是不释放的,有些对象需要重用的。类似这种我们就需要堆空间。

 (2)关于Struct 

通过反编译我们可以看到,struct在中间语言里实际上也是class,但是它继承了父类System.ValueType。也就是说,只要是继承了ValueType的,我们就可以认为是值类型

C#.Net学习笔记——CLR核心机制,c#,.net,学习

1、对于结构体,我们可以把它当作一个变量直接声明,也可以通过构造函数的方式new出来(结构体的构造函数必须包含所有字段和属性),但是无论哪种方式它都是值类型

C#.Net学习笔记——CLR核心机制,c#,.net,学习C#.Net学习笔记——CLR核心机制,c#,.net,学习

  (3)关于Class

引用类型分布在堆上面,变量(左边)是在栈上的,值(右边)是在堆上的

1、new的时候去堆开辟内存,分配一个地址

2、调用构造函数(因为在构造函数里可以使用this),才执行构造函数

3、把引用传给变量

C#.Net学习笔记——CLR核心机制,c#,.net,学习

问题思考:

我们有一个类(ReferenceTypeClass),这个类有一个字段int valueTypeField和一个方法Method,方法Method内又声明了一个int valueTypeLocalVariable类型的字段。请问ValueTypeFieldValueTypeLocalVariable分别位于堆还是栈?

C#.Net学习笔记——CLR核心机制,c#,.net,学习

答案:valueTypeField是位于堆里,valueTypeLocalVariable是位于栈里。

因为对象都在堆里,那么对象里面的属性也在堆里。而方法内声明的变量是在栈里,当调用我们的方法的时候,线程栈会给声明一个临时变量,是一个全新的局部变量。

总结:方法的局部变量:根据变量自身决定,跟所在环境没关系

           对象是引用类型,其属性/字段都在堆里面

           对象是值类型,其属性/字段,值类型就在栈里,引用类型就在堆里。

引用类型任何时候都在堆里;值类型都在栈里,除非值类型所在对象是在堆里。

三、拆箱装箱(浪费性能)

1、装箱:值类型->引用类型

int i = 3;
object Value = i;

2、拆箱:引用类型->值类型

object Value = 10;
int k = (int)Value;

3、拆箱装箱只能发生在父子类里面?因为这样才能转换。

四、特别对象——字符串

1、string是一个引用类型

思考1:string是一个引用类型,下面例子中声明了一个student和student2。student2=student,使得他们指向同一内存 “哈哈” 。但是为什么在student2赋新值后student不会跟着改变。

   private void button17_Click(object sender, EventArgs e)
        {
            string student = "哈哈";
            string student2 = student;
            Log.Info(student + " " + student2);
            student2 = "1234";
            Log.Info(student + " " + student2);
        }

答案:因为赋值其实new了一个新的string,重新开辟内存,返回引用。

        改了student2的值,但不是修改内存;string字符串的内存是不可变的

思考2:看案例,student和student2都是指向不同的内存,当我们重新给studeng2赋值并且这个值与student的值相等。按照上面的理论,他们的指向应该都是各自的内存,只不过他们的值恰好相等。思考一下他们都指向哪?

        private void button17_Click(object sender, EventArgs e)
        {
            string student = "哈哈";
            string student2 = "呵呵";
            student2 = "哈哈";
            Log.Info(object.ReferenceEquals(student, student2));
        }

答案:实际上他们还是指向了同一片内存。这就是我们CLR的机制,CLR内存分配字符串的时候,会查找相同值,有就重用。因此他们会指向相同内存以节约内存。

不可变是因为享元,可能有多个变量指向同一字符串,字符串变化了,多个变量都会受影响。

还因为堆里面的内存是连续分配的,如果变长度,会导致大量数据的移动。所以不如重新分配一个。

五、垃圾回收

(1)产生垃圾的原因:

1、值类型出现在线程栈:用完自己就结束,变量-值类型都会释放的。

2、引用类型出现在堆里:全局就一个堆,空间有限,所以才需要垃圾回收。

3、操作系统里面,内存是链式分配的,可能有碎片

4、CLR堆里边:连续分配(数组),空间有限,节约空间

(2)GC发生时机:

1、GC发生在New的时候,New一个对象时,会开辟内存在堆里边

2、New的时候看看空间够不够,不够的话就要GC了

3、定时程序,24小时执行一次,但是对象不会被回收,因为24小时之后你才会new,这个才能发生GC

4、静态不可能被回收 静态持有的引用也不会被回收

5、类似于下图这种情况,我们写了一个方法,方法内声明了Student和Class和一个int类型的变量。当方法执行结束后,值类型的i就会被直接回收,而引用类型的new Class则丢失引用,但是内存不会被自动回收,产生GC。

     private static Student _student = new Student()
        {
            Id = 1,
            Name = "Test",
        };
        public static void Show()
        {
            Student student = _student;
            Class @class = new Class()
            {
                Id = 1,
                CLassName = "Test",
            };
            int i = 3;  //会被GC
        }

6、主动GC

GC.Collect();

怎么回收?

什么是垃圾?垃圾是完全访问不到的东西

new的时候发现内存不够了,就去遍历所有堆的对象,标记访问不到,然后启动一个线程来清理内存。

移除标记了的对象,其他挪动,然后整齐摆放,所有这个时候全部线程停止,不允许操作内存。

为了促进垃圾回收,把对象赋值成null。其实不对,没有意义,垃圾回收是因为访问不到

 六、优化策略

1、首次GC前,全部对象都是0级。

2、第一次GC后,还保留的对象叫1级

3、回收先找1级对象,如果空间还不够,再去找1级对象,这之后,还存在的对象变成2级,2级还不够就内存溢出了

4、越是最近分配的,越是会被回收。比如for循环创建对象

因为回收过了,之前的内存可能是常驻内存,所以就从最近开始回收。

  七、析构函数

1、~Student 析构函数是用来释放非托管资源的,等着GC的时候去把非托管资源释放掉,系统自动执行。非托管资源就是管理不到的一些资源,包括数据库连接、打开的文档等。

 八、Using

1、下面可以说是等同关系,Using本质上来说只是一种语法糖

using(Student student = new Student())
{
    Id = 234
}
try
{
    Student student = new Student()
    {
        Id=234
    }
}
finally
{
    //调用的dispose()
}

2、Dispose() 主动释放,方法本身是没有意义的,我们需要在方法里面实现堆资源的释放

     而不是说对象释放的时候会自动去调用Dispose方法。

3、GC不会调用,而是用对象时,使用者主动调用这个方法。文章来源地址https://www.toymoban.com/news/detail-816205.html

到了这里,关于C#.Net学习笔记——CLR核心机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • .NET 6和.Net Core学习笔记:什么是.NET Core

    NET是开发平台 .NET是 .NET Framework、.NET Core、Xamarin/Mono的统称。 .NET Framework:近20年历史,.NET简称的最早拥有者,用于开发Windows程序。 Xamarin/Mono主要做移动开发:Xamarin、Unity。Mono也能做Web等跨平台开发,但主要专注移动端。 .NET Core:免费、跨平台、开源。 跨平台:程序可以运

    2024年02月08日
    浏览(45)
  • .NET 6和.Net Core学习笔记:.NET Core的重要问题

    什么是C#? .NET中主要的开发语言。 推荐C#书籍:《C#图解教程》,《C#入门经典》 尽管绝大部分用法都没变,但是.NET Core不是 .NET Framework的升级版,无法直接升级 绝大部分用法没有变,但又有部分是不能使用的。 又被微软坑了? .NET Framework白学了? 软件开发界的技术是不断

    2024年02月04日
    浏览(103)
  • 基于可变形卷积和注意力机制的带钢表面缺陷快速检测网络DCAM-Net(论文阅读笔记)

    原论文链接-DCAM-Net: A Rapid Detection Network for Strip Steel Surface Defects Based on Deformable Convolution and Attention Mechanism | IEEE Journals Magazine | IEEE Xplore DCAM-Net: A Rapid Detection Network for Strip Steel Surface Defects Based on Deformable Convolution and Attention Mechanism(论文标题) 带钢 (the strip steel)表面缺陷检测

    2024年02月04日
    浏览(50)
  • C# .Net学习笔记—— 加密和解密算法

    1、MD5不可逆加密 2、Des对称可逆加密 3、RSA非对称可逆加密 4、数字证书SSL 调用 得出结果 * 通过上面结果可以得出规律 MD5可以得到一串定长的随机编码 传入的字符串或者文件相同,得到的编码是相同的 只要稍微有一点不同得到的MD5都是不同的 1、账号登陆,数据库内防止看

    2024年01月22日
    浏览(50)
  • .NET 6学习笔记(8)生成自签证书

    上一篇我们通过导出IIS Express的自签证书,供ASP.NET Core程序启用HTTPS。本篇我们讨论如何生成自签证书。 自签证书的生成,有多种方式。比如OpenSSL或PowerShell都可以通过命令生成证书。对于.NET程序,也有System.Security.Cryptography.X509Certificates命名空间下,对应的C#类来实现。 首先

    2024年02月03日
    浏览(34)
  • .NET 面向对象程序设计 —— 学习笔记 详细版

            开始考虑通过封装、继承、多态把程序的耦合度降低(传统印刷 术的问题就在于所有的字都刻在同一版面上造成耦合度太高所制),开始用设计模式使得程序更加的灵活,容易修改, 并且易于复用。         大鸟说:“且先不说出题人的意思,单就你现在的

    2024年04月26日
    浏览(40)
  • .NET Core基础到实战案例零碎学习笔记

    前言:前段时间根据 [老张的哲学] 大佬讲解的视频做的笔记,讲的很不错。此文主要记录JWT/DI依赖注入/AOP面向切面编程/DTO/解决跨域等相关知识,还包含一些.NET Core项目实战的一些案例。我是西瓜程序猿,感谢大家的支持! 1.1.1-.NET Croe简介 (1)为什么要学习.NET Core? .NET

    2024年02月12日
    浏览(38)
  • XP-CLR分析学习笔记

    生物信息学和遗传学是相互交织的两个学科,共同致力于解读生物体内复杂的基因信息。这些信息有助于理解物种的演化,疾病的起因,以及个体差异等方面。 XP-CLR( Cross Population Composite Likelihood Ratio )分析是其中一个重要的分析方法,主要用于检测不同种群间由于自然选择

    2024年02月10日
    浏览(27)
  • Rx.NET in Action 第二章学习笔记

    本章节涵盖的内容: 不使用Rx的工作方式 向项目中添加Rx 创建你的第一个Rx应用程序 Rx 的目标是协调和统筹来自社交网络、传感器、用户界面事件等不同来源的基于事件的异步计算。例如,建筑物周围的监控摄像头和移动传感器会在有人靠近建筑物时触发,并从最近的摄像头

    2024年02月12日
    浏览(42)
  • C# .Net学习笔记—— 异步和多线程(Thread)

     注意:现在不建议使用 thread.Suspend(); //线程挂起                                  和 thread.Resum();   //唤醒线程 thread.Abort(); //销毁,方法是抛异常,也不建议使用 1、Join 线程等待 2、thread.ThreadState; //线程状态 3、thread.IsBackground; (i)默认是前台线程,启动之后一定要

    2024年02月02日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包