尽量在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这或许不是很有必要,但这绝对是一个好的习惯,试想一个项目中,如果将某个静态变量作为全局的缓存,如果没有做过期策略,一旦项目运行,那么它所占的内存空间只增不减,最终顶爆机器内存,所以,有个建议就是:尽量地少用静态变量。

最新文章

  1. Learn JavaScript(面向对象的程序设计01)
  2. STM32 MX Cube生成的工程中 使用printf向Uart发送数据
  3. [BZOJ1072][SCOI2007] 排列prem
  4. ES6中generator传参与返回值
  5. javascript函数中的三个技巧【一】
  6. FactoryBean的使用
  7. SpringJDBC
  8. [iOS]开发者证书和描述文件的作用
  9. .NET调用osql.exe执行sql脚本创建表和存储过程
  10. AddBinary
  11. BigDecimal工具类处理精度计算
  12. 【转载】 Spark性能优化:资源调优篇
  13. php开启fileinfo扩展
  14. 分布式事务2PC_PENDING异常处理
  15. POJ3714 Raid 分治/K-D Tree
  16. Java链式异常
  17. Git 创建操作
  18. 1.phpcms 伪静态
  19. 《DSP using MATLAB》Problem 3.2
  20. 最值得阅读学习的 10 个 C 语言开源项目代码

热门文章

  1. 英语NanyangJade南阳玉NanyangJade独山玉
  2. Qt固定窗口大小
  3. Vue+ElementUI 安装与应用
  4. pycharm 配置使用 flake8 进行语法检测
  5. python_机器学习_最临近规则分类(K-Nearest Neighbor)KNN算法
  6. va_list 、va_start、 va_arg、 va_end 使用说明【转】
  7. pip安装模块使用国内镜像源加速安装
  8. C++ vector初始化方式
  9. 【oracle】存储过程中获取delete语句执行后删除的记录数
  10. 解决PEnetwork启动的时候提示&quot;An error occured while starting the &quot;TCP/IP Registry Compatibility&quot; Service (2)!&quot;程序将立即退出的问题