zoukankan      html  css  js  c++  java
  • C# 《编写高质量代码改善建议》整理&笔记 --(四)资源管理&序列化

    1.显示释放资源需继承接口IDisposable

    什么是资源:C#中每一个类型都代表一种资源,而资源又分为以下两类。

    托管资源:由CLR管理分配和释放的资源,即从CLR里new出来的对象。

    非托管资源: 不受CLR管理的对象,如windows内核对象,或者文件,数据块连接,套接字,COM对象等。

    如果我们的类型使用到了非托管资源,或者需要显示地释放托管资源,那么需要让类型继承接口IDisposable。

    相当于告诉调用者:类型对象时需要显示的释放资源的,你需要调用类型的Dispose方法。

       public class AnotherClass:IDisposable
        {
            public void Dispose()
            {
                Dispose();
            }
        }
        public class SampleClass:IDisposable
        {
            private IntPtr nativeResource = Marshal.AllocHGlobal(100);
            private AnotherClass managedResource = new AnotherClass();
            bool disposed = false;
            public void Dispose()
            {
                Dispose();
                GC.SuppressFinalize(this); //通知垃圾回收器不再调用析构器
            
            }
    
            /// <summary>
            /// 不是必要的,提供一个close方法仅仅为了更符合其他语言的规范。
            /// </summary>
            public void Close()
            {
                Dispose();
            }
            /// <summary>
            /// 防止程序员忘记显示的调用Dispose
            /// </summary>
            ~SampleClass()
            {
                Dispose();
            }
    
            /// <summary>
            /// 非密封类修饰用protected virtual
            /// </summary>
            /// <param name="isDisposing"></param>
            protected virtual void Dispose(bool isDisposing)
            {
                if(disposed)
                {
                    return;
                }
    
                //清理托管资源
                if(isDisposing)
                {
                    if(managedResource!=null)
                    {
                        managedResource.Dispose();
                        managedResource = null;
                    }
                }
    
                //清理非托管资源
                if(nativeResource!=IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(nativeResource);
                    nativeResource = IntPtr.Zero;
                }
                disposed = true;
            }
        }

    2.即使提供了显示释放资源,也应该在终结器中提供隐式清理

     终结器(即析构函数),其意义在于我们不奢望类型的调用者会主动调用Dispose方法,基于终结器会被垃圾回收器调用

    的特点,他被用于资源释放的补救措施。

     如果调用者已经调用Dispose方法进行了显示地资源释放,那么隐式释放资源(终结器,析构函数)也就没必要运行了,

    FCL中的类型GC提供了静态方法SupressFinalize来通知垃圾回收器。GC.SupressFinalize(this)

     public class TestClass:IDisposable
        {
            public void Dispose()
            {
                Dispose();
                GC.SuppressFinalize(this);//这样如果调用过,则不会再调用析构函数,如果不加,则还会调用析构函数
            }
    
            ~TestClass() //写析构以防忘记调用Dispose的时候,自动调用该函数
            {
                Dispose();
            }
        }

     3.何时及时释放资源

        垃圾回收器什么时候进行回收工作?

        1)系统具有较低的物理内存。

        2)由托管堆上已分配的对象使用的内存超出了可接受的范围。

        3)主动调用GC.Collect().

      垃圾回收机制中海油一个“代”的概念。一共分为3代:0,1,2代。第0代包含一些短期生存的对象。如局部变量fileStream就是一个短期生存的对象。第一次执行fileStream就被丢到了第0代,但此刻不进行垃圾回收。当第0代满了的时候,运行时会认为现在低内存的条件已满足,那时才会垃圾回收。在回收之前,他实际没有用,却始终占据着内存不放,这对系统是极大的浪费,并且浪费还会干扰程序的正常运行。(始终占据文件资源,导致我们不能再次使用这个文件资源)

      不及时释放资源还会带来另外一个问题:如果类型本身继承了IDisposable接口,垃圾回收机制虽然会自动帮我们释放资源,但是这个过程却延长了,因为它不是在一次回收中完成所有的清理工作。因为fileStream继承了IDisposable接口,故在第一次垃圾回收的时候,垃圾回收器会调用fileStream的终结器,然后等待下一次的垃圾回收,这时fileStream对象才可能被真正的回收掉。

    4.必要时将不再使用的对象引用赋值为null

      在执行垃圾回收时,类型的对象被回收时,类型的静态字段并没有被回收。

      我们需要在析构函数中对这静态字段额外置为null。

      在实际工作中,一旦我们感觉到自己的静态引用类型参数占用的内存空间比较大,并且用完不会再使用,便可以立刻将其赋值为null。(好习惯,因为静态变量,一旦创建,永远不会离开,还有尽量少使用静态变量。)

    5.序列化

      定义:把对象转变成流,称为序列化,反之,将流转变为对象称为反序列化。

      用途:

          ①把对象保存到本地,在下次运行程序的时候,恢复这个对象。

          ②把对象传到网络中的另外一台终端上,然后在此终端还原这个对象。

          ③把对象复制到系统的粘贴板上,然后用Ctrl+V恢复这个对象。

       1)为无用字段标注为不可序列化

          ①节省空间。类型在序列化后往往会存储到某个地方,如数据库,硬盘或内存中,如果一个字段在反序列化后不需要保持

    状态,那就不应该被序列化,这会占用宝贵的空间资源。

         

  • 相关阅读:
    SQL SERVER 表分区测试备忘
    理解信息系统中的流程与工序
    获取最后插入的id另外方法
    asp.net 项目在 IE 11 下出现 “__doPostBack”未定义 的解决办法
    定制应用Repeater 、ListView的模版
    JavaScript学习笔记——简单无缝循环滚动展示图片的实现
    JavaScript学习笔记——JS中的变量复制、参数传递和作用域链
    CSS学习笔记——定位position属性的学习
    CSS学习笔记——CSS中定位的浮动float
    CSS学习笔记——盒模型,块级元素和行内元素的区别和特性
  • 原文地址:https://www.cnblogs.com/u3ddjw/p/9092853.html
Copyright © 2011-2022 走看看