C#内存分配和回收

包含内容:

  1. C#处理内存分配和回收策略
  2. C#执行类型检查方法
  3. C#与其他编程语言的互操作,跨平台处理

CLI,Common Language Infrastructure, C#编译和执行所依赖的一个公共语言基础结构。

C#生成一种中间语言指令,即CIL。在执行时,CIL才被转换为机器码。同时,还需要运行时负责加载和运行程序,提供类似安全保障,垃圾回收等额外服务。以上内容都被写入了CLI中,成为国际性规范,所以说CLI是C#的执行环境和与其他语言交互的一个规范。

跟C与C++不一样的是,C和C++是直接编译成机器码,所以这些语言的平台是底层操作平台和机器指令集,即Linux,Windows等。而C#的底层平台是运行时,运行时可以理解CIL语言,使用内部的即时编译器(Just-In-Timecompiler)完成CIL到机器码的编译过程。当程序安装或者执行的时候便可能发生JIT编译,大多数发生在执行时。

.NET包含NGEN工具,能在运行程序之前将代码编译成机器码,会评估机器的特性,生成高效的代码,如Unity项目中的LuaJit文件夹。在安装程序时使用NGEN,可以缩短程序的JIT编译导致的启动时间。另外,CLI也允许解释执行,这个特性使得C#能够很好地与脚本语言一起执行。

VS2015后的版本支持本机.NET,可以在创建部署版本的时候,将C#代码编译成本机机器码。在运行时下执行的代码称为托管代码,数据所需的内存是运行时自动分配回收的。由于代理的存在,可以存在一些额外的服务,比如异常处理,安全信息访问等。

在运行时中内置了垃圾回收此服务,具体的工作方式并不固定。被垃圾回收的对象不一定会进行确定性回收,即在定义好的,编译时已知的位置进行回收。垃圾回收器只负责内存管理,而不会释放除了内存以外的资源。

大多数CLI使用的是generational, compacting, mark-and-sweep的回收算法。下面简单解释:

  • generational : 经历过垃圾回收且存活下来的对象,会比只存活过 短时间的对象,更晚地被清理掉。
  • compacting : 将被回收的对象会被压缩到一起,确保没有脏空间。
  • mark-and-sweep : 每次执行辣鸡回收的时候,都会标记出将要回收的对象。

使用压缩机制使得新对象能快的实例化,而不需要搜索内存找分配空间,同时降低了分页的概率,因为同一页能存储更多对象。另外,垃圾回收会考虑到机器资源,当计算机内存余量较大时很少清理资源。

运行时的另一个优点是它的类型检查能力,能够防止非法类型转换导致的缓冲区溢出安全漏洞。在运行时,会进行以下的类型检查:

  • 变量和变量引用的数据都有类型,变量的类型兼容引用的数据类型。
  • 局部分析一个类型,确定需要什么权限来执行该类型的成员
  • 每个类型都有一组编译时定义的方法和数据,,强制规定了可以访问方法和数据的类型。

当有相应权限时,可以通过反射机制绕过分装和访问修饰符,反射机制允许浏览类型成员,晚期绑定,在对象中查找特定构造,调用类型成员等功能。运行时根据权限允许或者禁止特定类型的操作,根据程序创建者控制执行。CAS,Code Access Security ,还能识别代码的位置,比如本地的代码比起互联网的代码受信任,提供者的身份标志被嵌入程序证书。

平台可移植性,指的是不需重新编译,代码的移植工作由运行时来实现。必须不能使用某个平台的API,但是这又带来了更多的不便利。在VS中有支持通用应用程序。

C#内存分配机制基于托管堆(managed heap)和垃圾回收(garbage collection)。 1. 托管堆(Managed Heap):在C#中,所有的对象都存储在托管堆中。托管堆是一块被.NET运行时分配的内存区域,用于存储托管对象的实例和数据。托管堆是按照分代(generational)的方式进行管理,将对象分为不同的代,根据对象的生命周期和使用频率来优化垃圾回收效率。 2. 对象创建:当使用`new`关键字创建一个对象时,CLR(Common Language Runtime)会在托管堆上分配一块足够大小的内存来存储对象的数据。CLR会进行必要的初始化工作,如设置对象头信息等。 3. 垃圾回收C#采用垃圾回收机制来管理内存分配和释放。垃圾回收器会定期扫描托管堆,标记那些仍然被引用的对象,并清除那些没有被引用的对象。垃圾回收器使用了根引用(root references)来确定哪些对象是活动的,其他对象则被认为是可回收的。 4. 引用计数:在某些情况下,C#的垃圾回收器可能会使用引用计数来辅助确定对象是否可以被回收。每当一个对象被引用时,引用计数加1;当一个引用被取消或离开作用域时,引用计数减1。当引用计数为0时,对象可以被回收。 需要注意的是,C#的垃圾回收器并非实时的,而是在需要的时候进行垃圾回收。具体的垃圾回收策略和算法由.NET运行时环境负责管理,而开发人员无需手动进行内存管理。不过,开发人员可以通过使用`IDisposable`接口手动释放一些非托管资源,以提前释放内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值