n1cef1sh's Blog

C#编译

先将源码编译为中间代码MSIL(Microsoft Intermediate Language),再由.net中的CLR(公共语言运行时,一种运行时环境,运行代码并提供使开发过程更轻松的服务)将中间代码编译成机器码。
Java是先编译后解释,而C#是两次编译。

资源

资源就是程序中可利用的数据,例如字符串、图片等。
访问资源的步骤:

托管资源&非托管资源

垃圾?

什么是垃圾?
啥都不会就是辣鸡
.NET两大类型,值类型和引用类型。值类型分配在栈上,不需要GC回收;引用类型分配在堆上,需要GC回收。
一个引用类型对象或者其包含的子对象没有任何引用是有效的,则系统认定为垃圾。

内存中的垃圾分为两种。

Garbage collection happens automatically when a request 
for memory can't be satisfied using available free memory

GC发生的时机,就是相应的堆达到了阈值,因为堆也有大小限制,并不是无限的。

为了优化性能,使用了generation“代”的概念。将托管堆分为三代:第0代、第1代和第2代。垃圾回收算法基于几个普遍原理:

关于代数,官方文档的解释。

- 第 0 代。   
这是最年轻的代,其中包含短生存期对象。  
短生存期对象的一个示例是临时变量。垃圾回收最常发生在此代中。  
新分配的对象构成新一代对象,并隐式地成为第 0 代集合。  
大多数对象通过第 0 代中的垃圾回收进行回收,不会保留到下一代。
如果应用程序在第 0 代托管堆已满时尝试创建新对象,垃圾回收器将执行收集,以尝试为该对象释放地址空间。 垃圾回收器从检查第 0 级托管堆中的对象(而不是托管堆中的所有对象)开始执行回收。 单独回收第 0 代托管堆通常可以回收足够的内存,这样,应用程序便可以继续创建新对象。
- 第 1 代。  
这一代包含短生存期对象并用作短生存期对象和长生存期对象之间的缓冲区。  
垃圾回收器执行第 0 代托管堆的回收后,会压缩可访问对象的内存,并将其升级到第 1 代。 因为未被回收的对象往往具有较长的生存期,所以将它们升级至更高的级别很有意义。 垃圾回收器在每次执行第 0 代托管堆的回收时,不必重新检查第 1 代和第 2 代托管堆中的对象。
如果第 0 代托管堆的回收没有回收足够的内存供应用程序创建新对象,垃圾回收器就会先执行第 1 代托管堆的回收,然后再执行第 2 代托管堆的回收。 第 1 级托管堆中未被回收的对象将会升级至第 2 级托管堆。
- 第 2 代。  
这一代包含长生存期对象。 长生存期对象的一个示例是服务器应用程序中的一个包含在进程期间处于活动状态的静态数据的对象。
第 2 代托管堆中未被回收的对象会继续保留在第 2 代托管堆中,直到在将来的回收中确定它们无法访问为止。

当条件得到满足时,垃圾回收将在特定代上发生。 回收某个代意味着回收此代中的对象及其所有更年轻的代。 第 2 代垃圾回收也称为完整垃圾回收,因为它回收所有代中的对象(即托管堆中的所有对象)。
垃圾回收中未回收的对象也称为幸存者,并会被提升到下一代。

清理非托管资源

测试实践

待建设

小结

本文源自对using语句的学习,在搜索资料的过程中对GC机制有一个初步的简单了解,但是没有更深入的实践和理解,留作之后用到时再进行学习。

参考

浅谈c#垃圾回收机制(GC)

微软官方文档