zoukankan      html  css  js  c++  java
  • c#的IDisposable

    尽量在using中使用非托管资源

    1.实现Dispose方法

    2.提取一个受保护的Dispose虚方法,在该方法中实现具体的释放资源的逻辑

    3.添加析构函数

    4.添加一个私有的bool类型的字段,作为释放资源的标记

    例子:

    public class MyClass : IDisposable
    {
    /// <summary>
    /// 模拟一个非托管资源
    /// </summary>
    private IntPtr NativeResource { get; set; } = Marshal.AllocHGlobal(100);
    /// <summary>
    /// 模拟一个托管资源
    /// </summary>
    public Random ManagedResource { get; set; } = new Random();
    /// <summary>
    /// 释放标记
    /// </summary>
    private bool disposed;
    /// <summary>
    /// 为了防止忘记显式的调用Dispose方法
    /// </summary>
    ~MyClass()
    {
    //必须为false
    Dispose(false);
    }
    /// <summary>执行与释放或重置非托管资源关联的应用程序定义的任务。</summary>
    public void Dispose()
    {
    //必须为true
    Dispose(true);
    //通知垃圾回收器不再调用终结器
    GC.SuppressFinalize(this);
    }
    /// <summary>
    /// 非必需的,只是为了更符合其他语言的规范,如C++、java
    /// </summary>
    public void Close()
    {
    Dispose();
    }
    /// <summary>
    /// 非密封类可重写的Dispose方法,方便子类继承时可重写,当传入true时代表要同时处理托管资源和非托管资源;而传入false则只需要处理非托管资源即可
    /// </summary>
    /// <param name="disposing"></param>
    protected virtual void Dispose(bool disposing)
    {
    if (disposed)
    {
    return;
    }
    //清理托管资源
    if (disposing)
    {
    if (ManagedResource != null)
    {
    ManagedResource = null;
    }
    }
    //清理非托管资源
    if (NativeResource != IntPtr.Zero)
    {
    Marshal.FreeHGlobal(NativeResource);
    NativeResource = IntPtr.Zero;
    }
    //告诉自己已经被释放
    disposed = true;
    }
    }

    当满足以下条件之一时,GC才会工作

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

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

    3.手动调用GC.Collect方法,但几乎所有的情况下,我们都不必调用,因为垃圾回收器会自动调用它。

    静态变量不被释放(即使赋值为null也不会被编译器优化),是因为类型的静态字段一旦被创建,就被作为“根”存在,基本上不参与GC,所以GC始终不会认为它是个垃圾,而非静态字段则不会有这样的问题。

    所以在实际工作当中,一旦我们感觉静态变量所占用的内存空间较大的时候,并且不会再使用,便可以将其置为null,最典型的案例就是缓存的过期策略的实现了,将静态变量置为null这或许不是很有必要,但这绝对是一个好的习惯,试想一个项目中,如果将某个静态变量作为全局的缓存,如果没有做过期策略,一旦项目运行,那么它所占的内存空间只增不减,最终顶爆机器内存,所以,有个建议就是:尽量地少用静态变量。

  • 相关阅读:
    linux给用户添加sudo权限
    VirtualBox下安装ubuntu图文教程以及软件安装
    线程池代码(通用版)
    linux下配置jdk+tomcat
    线程池代码(加强版)
    线程池的理解与简单实现(学习版)
    条件变量pthread_cond_wait()和pthread_cond_signal()详解
    五种编程模型
    Linux线程退出、资源回收、资源清理的方法
    数据结构
  • 原文地址:https://www.cnblogs.com/mcyushao/p/11907696.html
Copyright © 2011-2022 走看看