C#随笔

1.装箱和拆箱
①装箱操作会将值类型转换为引用类型,新创建的引用相当于箱子,分配在堆内存上,含有原值的一份拷贝
②装箱时,会将原本值类型实现的接口也拷贝一份,拆箱时,再将接口拷贝一份到栈上
③性能:如果值类型必须被频繁装箱,那么在这些情况下最好避免使用值类型(例如在诸如 System.Collections.ArrayList 的非泛型集合类中)。 可通过使用泛型集合(例如 System.Collections.Generic.List)来避免装箱值类型。 装箱和取消装箱过程需要进行大量的计算。 对值类型进行装箱时,必须创建一个全新的对象。 这可能比简单的引用赋值用时最多长 20 倍。 取消装箱的过程所需时间可达赋值操作的四倍。 有关详细信息,请参阅装箱和取消装箱。
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 方法执行完成后,对象才会被真正回收。

posted @ 2025-02-10 22:31  Emiria  阅读(10)  评论(0)    收藏  举报