快速理解.NET Framework (3)

来源:百度文库 编辑:神马文学网 时间:2024/04/20 11:21:40
理解JIT编译器
JIT编译器作为CLR的一个完整的部分将MSIL代码编译成本地代码并且实时执行整批代码。代码将会被缓存而下次就会从缓存中读取代码再次编译执行(翻译不出来)

JIT执行进程
CLR类加载器加载MSIL代码并且将元数据加载到内存;代码管理器调用WinMain或DllMain方法。JIT编译器在其入口方法执行之前编译这个方法。代码管理器将对象放置在内存中并控制代码的执行。垃圾收集器实现对管理堆的周期性检查识别应用程序的无效对象。
程序执行时类型检查器确保所有对象和值以及对象和值的引用有其合法的类型。类型检查器也保证代码的唯一合法操作,否则就抛出异常。代码在运行时由CLR控制。CLR在以下行为上增强安全性:
像硬盘一样控制和访问系统资源 控制和访问网络连接 控制和访问其他硬件资源
被管理代码执行
被管理代码执行被认为是由CLR执行的进程,具体有以下几个方面:
CLR加载MSIL和应用元数据 CLR执行本地代码, CLR提供自动内存管理 被管理的执行也实现JIT编辑 封装类型安全, 增强安全性 处理异常
被管理的执行进程
被管理代码是自解释性的代码,它在.NET框架中给CLR多运行时服务的信息。 这些信息在PE文件里以元数据的形式被存储在MSIL代码中。元数据信息会描述代码包含的类型。 被管理数据是由垃圾收集器自动被分配和释放的。被管理代码能被被管理数据理解而非管理数据能被被管理理解。(翻的不正确)
内存管理
自动内存管理意味着当对象创建时不需要编写代码分配内存或是当应用程序不需要对象时释放内存。 自动内存管理的进程包括下列任务:
?分配内存
当一个进程被初始化时,运行时保留了一个连续的地址空间而不为它分配任何存储空间。 这个保留的地址空间被叫做托管堆。托管堆在下一个对象被放置的地方保留了一个指针。 当一个应用程序使用new操作符创建一个对象时,new操作符检查堆内对象所需的内存是否可用。 当下一个对象创建的时候,垃圾收集器在托管堆分配内存给对象。 在托管堆分配内存给对象的时间比分配非托管堆内存耗时要少。 在非托管堆中,指向内存的指针在链表数据结构中维护。因此,分配内存需要通过操纵链表,寻找能够容纳它的较大的内存块。(此处原文不全) 与访问非托管内存相比你能更快地访问托管内存的对象,因为在托管内存分配时,对象总是在托管的地址空间中分配。
?释放内存
 
 
?分配内存
当一个进程被初始化时,运行时保留了一个连续的地址空间而不为它分配任何存储空间。 这个保留的地址空间被叫做托管堆。托管堆在下一个对象被放置的地方保留了一个指针。 当一个应用程序使用new操作符创建一个对象时,new操作符检查堆内对象所需的内存是否可用。 当下一个对象创建的时候,垃圾收集器在托管堆分配内存给对象。 在托管堆分配内存给对象的时间比分配非托管堆内存耗时要少。 在非托管堆中,指向内存的指针在链表数据结构中维护。因此,分配内存需要通过操纵链表,寻找能够容纳它的较大的内存块。(此处原文不全) 与访问非托管内存相比你能更快地访问托管内存的对象,因为在托管内存分配时,对象总是在托管的地址空间中分配。
?释放内存
垃圾收集器周期性地应用程序不再需要的对象中释放内存。 每个应用程序有一组根的集合。一些根的集合指向在托管堆存储位置。每个根指针或者引用托管堆中的一个对象或是被置成空。 一个应用程序的一些根的集合由线程栈上的全局静态指针,局部变量和引用对象参数组成。 JIT编译器和运行时维护应用程序根的集合的列表。垃圾收集器使用这个列表创建从根的集合列表中获得的在托管堆中的对象图表。 当垃圾收集器开始运行,它把在托管堆中的所有对象都看作垃圾。 垃圾收集器通过应用程序的根的集合列表操作,这个列表定义了在应用程序中一些根的集合列表中有相应的引用的对象并对可获得的对象标记。 垃圾收集器也把这样的对象作为可获得对象。(不知道是什么意思) 垃圾收集器认为所有托管堆中不可获得的对象是垃圾。 垃圾收集器通使用收集进程释放垃圾对象空间。 垃圾收集器使用内存复制功能来压缩托管堆中的对象。 垃圾收集器更新应用程序根的集合列表中的指针,使得指向较早的应用程序一些根的集合正确指向对象。 垃圾收集器使用高度优化的机制完成垃圾收集。它把托管堆中的对象分为三级:0、1、和2。第0级包括最近被创建的对象。 垃圾收集器开始在第0级收集不可获得的对象。接着,垃圾收集器紧缩内存并将可获得对象提升为第1级。 幸免于收集进程收集的对象被提升为更高的级别。 垃圾收集器在第1级和第2级搜索不可获得的对象,仅当通过第0级对象的收集进程释放的内存不足以创建一个新的对象时。 垃圾收集器为所有应用程序创建的托管对象管理内存。 垃圾收集器能通过在对象等Dispose方法中提供清除代码来显式释放这些系统资源。 我们在对象完成工作后需要显式调用Dispose方法。
?实现终止化器
终止化器进程允许一个对象在垃圾收集器启动之前完成清理工作。 Finalize方法确保了即使客户没有显式调用Dispose方法,所使用的资源在对象被垃圾收集时也会从内存被释放。 在垃圾收器集进行垃圾收集时识别对象是垃圾后,它在释放内存前调用对象的Finalize方法。 终止化器是包含在对象收集之前被执行的清理代码的方法。执行清理代码的进程被叫做终结。Dispose和Finalize方法被叫做终止化器。 对象的Dispose方法会释放所有资源,包括它的父对象拥有的资源通过调用父对象的Dispose方法。 我们有两个方法执行Dispose方法: 类用户能够调将被销毁对象的Dispose方法,或者 Finalize方法能在终结过程中调用Dispose方法。
以下摘自网友 小新0574 的建议, 谢谢小新0574
2.在“释放内存 ”中提到的“根指针”,这个说法,我个人认为需要斟酌一下。原文是说“a set of roots”,一些根的集合,但把这里的根说成根指针,容易混淆,因为这个根由“global and static object pointers, local variables, and reference object parameters on a thread stack”组成,而这些成员不应该统称为“指针”
3.还有这个词“Finalizers”,<<.NET框架程序设计(修订版)>>的作者是翻译为终止化器,为觉得这个翻译比较好,“完成器”有点不妥,太字面化了,没有说明它的作用。