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

、堆栈内存分配

(1)基本介绍

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

谁来分配?        CLR来分配

1、值类型:struct  枚举

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

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

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

 (2)关于Struct 

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

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

  (3)关于Class

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

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

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

3、把引用传给变量

问题思考:

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

答案: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不会调用,而是用对象时,使用者主动调用这个方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/607866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Gartner发布2024年SASE融合战略路线图

向云计算和远程工作的转变增加了 SASE 需求,以实现从任何设备的安全访问。安全和风险管理领导者必须将网络和安全融合到一两个明确合作的 SASE 供应商产品中,并淘汰遗留的边界系统。 主要发现 安全访问服务边缘 (SASE) 框架为混合劳动力以及设备、分支机…

java基础之HashMap练习题

应用了 外循环,自循环,Lambda表达式,keySet()方法,values()方法,Entry对象 ,entrySet()方法 Map集合框架 1:(Map)关于下列Map 接口中…

AI问答系统与对话机器人服务(一)

知识要点 微软认知服务中知识库服务的申请与搭建 如何用REST API访问知识库数据 微软认知服务中机器人服务的申请与搭建 如何无缝集成知识库服务与机器人服务 建立知识库 什么叫QnA Maker? 知识库,就是人们总结出的一些历史知识的集合,存储、索引…

Windows 双网卡链路聚合解决方案

Windows 双网卡链路聚合解决方案 链路聚合方案1:Metric介绍操作 方案2:NetSwitchTeam介绍操作 方案3:NIC介绍操作 方案4:Intel PROSet 链路聚合 指将多个物理端口汇聚在一起,形成一个逻辑端口,以实现出/入…

办公文档,私人专用

一、安装Minio 1.1、创建文件夹,并在指定文件夹中下载minio文件 cd /opt mkdir minio cd minio touch minio.log wget https://dl.minio.io/server/minio/release/linux-amd64/minio1.2、赋予minio文件执行权限 chmod 777 minio1.3、启动minio ./minio server /…

Python3+Selenium+Chrome实现自动填写WPS表单

引言 本文通过python3、第三方python库Selenium和谷歌浏览器Chrome,完成WPS表单的自动填写。 开发环境配置 python3的安装:略,网上都有教程。 Selenium的安装:在命令行输入pip3 install selenium并回车即可完成安装,如…

(Matlab)基于CNN-Bi_LSTM的多维时序回归预测(卷积神经网络-双向长短期记忆网络)

目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、部分代码展示: 四、完整代码数据下载: 一、程序及算法内容介绍: 基本内容: 本代码基于Matlab平…

局域网IP地址冲突、环路的罪魁祸首是什么?

中午好,我的网工朋友。 这个时代,网络已经贯穿了人们的生活,对企业而言,办公信息化更是离不开网络支持。 为了提高安全管理和信息化水平,很多企业都建立了完善的办公信息系统,但一些企业在网络建设方面还…

适合培训协会搭建的培训机构管理系统开发方案

一、项目背景与目标 (一)项目背景 培训学校教务管理系统是培训机构数字化管理的必备系统,该系统功能大大提升机构办学的管理效率、提升机构在家长心中的专业度,市面上的培训机构管理系统收费越来越贵,为了给协会内培…

高功率电源PCB设计中变压器底层走线的关键要点

高功率电源的设计中,变压器起到了电能的传递与转换的重要作用。变压器下方的走线设计不仅涉及到电路的功率传输效率,还与电磁兼容性(EMC)、热管理以及电路的可靠性密切相关。 1. 走线布局 在进行变压器下方走线设计时&#xff0c…

Ubuntu 实时查看显存调用命令 free 及命令详解与原理说明(全)

Ubuntu 实时查看显存调用命令 free 及详解 文章目录 Ubuntu 实时查看显存调用命令 free 及详解1 free 作用1.1 语法:1.2 单独显示例子1.3 组合显示例子 2 输出介绍3 原理解释3.1 buff / cache(即 buffer / cache)3.1.1 buffer 缓冲区3.1.2 ca…

移动端对大批量图片加载的优化方法(二)

移动端对大批量图片加载的优化方法(二)Android 本篇主要从Android开发中可以使用到的对大批量图片加载的优化方法进行整理。 1.合适的图片格式 详情请参考移动端对大批量图片加载的优化方法(一)。 2.异步加载 图片加载可能会…

模板管理支持批量操作,DataEase开源数据可视化分析平台v2.2.0发布

2024年1月8日,DataEase开源数据可视化分析平台正式发布v2.2.0版本。 这一版本的功能升级包括:在“模板管理”页面中,用户可以通过模板管理的批量操作功能,对已有模板进行快速重新分类、删除等维护操作;数据大屏中&…

深圳易图讯科技VR三维电子沙盘系统

易图讯VR三维电子沙盘系统是一种结合虚拟现实技术的地理信息系统。它通过高精度三维模型,真实再现了地理环境、建筑布局和地形地貌。用户可通过VR设备沉浸式体验这一虚拟世界,进行各种交互操作,如缩放、旋转、移动等。系统还支持实时数据更新…

门店管理系统驱动智慧零售升级

在当今数字化经济的大潮中,实体门店正在经历一场由内而外的深度变革。门店管理系统以其高效、便捷和全面的功能特性,为实体店提供了高效的运营解决方案。 门店管理系统拜托了传统零售业对本地化软件的依赖,它将复杂的信息技术转化为易于获取…

2024十大开放式耳机品牌有哪些?公认好用的开放式耳机测评推荐

随着生活水平的提升,人们对音频设备的需求已经不再只是简单的声音输出,而是追求更高质量的听觉体验,而近几年出现的开放式耳机正是为了满足这一需求而诞生的,凭借着不入耳的设计带来了极致的佩戴体验,这种耳机也成为了…

如何克隆驱动器,不同的操作系统有不同的推荐软件

你需要将Windows或macOS安装迁移到新驱动器吗?你可以使用服务备份文件,也可以创建数据的完整一对一副本。通过克隆你的驱动器,你可以创建一个精确的副本。 一些业务级别的备份服务,如IDrive和Acronis,具有内置的磁盘克隆功能,是对正常文件备份的补充。但对于一次性克隆(…

SpringBoot+策略模式实现多种文件存储模式

一、策略模式 背景 针对某种业务可能存在多种实现方式;传统方式是通过传统if…else…或者switch代码判断; 弊端: 代码可读性差扩展性差难以维护 策略模式简介 策略模式是一种行为型模式,它将对象和行为分开,将行…

实现导航栏吸顶操作

一、使用VueUse插件 // 安装 npm i vueuse/core二、点击搜索useScroll 2.1搜索结果如图 三、使用 // 这是示例代码 import { useScroll } from vueuse/core const el ref<HTMLElement | null>(null) const { x, y, isScrolling, arrivedState, directions } useSc…

结构型设计模式——适配器模式

适配器模式 这个更加好理解&#xff0c;就是做适配功能的类&#xff0c;例如&#xff0c;现在手机没有了圆形耳机接口&#xff0c;只有Type-C接口&#xff0c;因此你如果还想要使用圆形耳机的话需要买个圆形接口转Type-C的转换器&#xff08;适配器&#xff09;&#xff0c;这…