C#随笔
1.装箱和拆箱
①装箱操作会将值类型转换为引用类型,新创建的引用相当于箱子,分配在堆内存上,含有原值的一份拷贝
②装箱时,会将原本值类型实现的接口也拷贝一份,拆箱时,再将接口拷贝一份到栈上
③性能:如果值类型必须被频繁装箱,那么在这些情况下最好避免使用值类型(例如在诸如 System.Collections.ArrayList 的非泛型集合类中)。 可通过使用泛型集合(例如 System.Collections.Generic.List
2.C#资源管理
①分为托管资源和非托管资源
托管资源:new 出来的对象
非托管资源:文件句柄、网络链接
②释放非托管资源:iDisposable接口或者Finalizier机制
③垃圾回收世代概念:垃圾回收主要在回收短生存期对象时发生。 为优化垃圾回收器的性能,将托管堆分为三代:第 0 代、第 1 代和第 2 代,因此它可以单独处理长生存期和短生存期对象。 垃圾回收器将新对象存储在第 0 代中。 在应用程序生存期的早期创建的对象如果未被回收,则被升级并存储在第 1 级和第 2 级中。 因为压缩托管堆的一部分要比压缩整个托管堆速度快,所以此方案允许垃圾回收器在每次执行回收时释放特定级别的内存,而不是整个托管堆的内存。
③finalizer:C#编译器在编译析构函数时,它会隐式地把析构函数的代码编译为等价于重写Finalize()方法的代码,从而确保执行父类的Finalize()方法。下面列出的C#代码等价于编译器为~MyClass()析构函数生成的IL:垃圾回收器四④:(GC)的工作流程如下:GC 定期检查托管堆中的对象,找出不再被任何引用的对象,标记为不可达后,
如果对象没有 Finalizer 方法,垃圾收集器在标记为不可达后,因为对象没有额外的清理任务需要在销毁前执行,所以垃圾收集器可以迅速且高效地回收其占用的内存。
如果对象有 Finalizer 方法,GC 会将这些对象放入“终结队列”(Finalization Queue)。
终结队列:存储所有需要调用 Finalizer 方法的对象。
终结线程:一个独立的线程,负责从终结队列中取出对象并调用它们的 Finalizer 方法。一个独立的终结线程(Finalizer Thread)会从终结队列中取出对象并调用它们的 Finalizer 方法。在 Finalizer 方法执行完成后,对象才会被真正回收。

浙公网安备 33010602011771号