处理并完成

Anonim

在编程语言中,对象在其存在期间只能具有变量,在实例化之后它不能被修改。因此,不能将相同的存储器单元分配给新值,因此需要某种自动存储器管理来管理未使用的空间。这些未使用的空间称为垃圾,高效内存管理的整个过程称为垃圾收集。

垃圾收集器的主要目的是将死对象与活动对象分开并回收空间以便重用。基本上,整个事情都在托管堆上运行,托管堆只是一个内存块,垃圾收集器会定期检查堆内存以便为新对象分配内存。有两种方法可以释放非托管资源,如文件和数据库连接:Dispose和Finalize。

本文将帮助您了解两者之间的区别。

什么是Dispose方法?

Dispose是用户告诉对象释放其资源而不是尝试再次访问对象的标准方法。 dispose方法通过使对象不可用来提供对显式内存清理的控制。

当用户调用Dispose()方法时,该对象应该释放其所有昂贵的资源,从而使其可以重用。它永远不会被垃圾收集器调用,只有在管理内存变得稀缺时才会发挥作用。名为“IDisposable”的特殊接口用于决定实现Dispose()的位置和方式。但是当dispose方法没有被调用时会发生什么?

什么是Finalize方法?

如果没有调用dispose方法,则回退计划是使用Finalize()方法进行清理。垃圾收集器调用它在释放内存之前执行最终资源清理。及时清理的概念在这里变得不适用,因为不是立即取消分配内存,而是将对象添加到终结队列中,以便稍后销毁。如果出现编程错误,则Finalize更像是一个安全措施,并且dispose不会清理资源,在这种情况下,垃圾收集器调用Finalize()方法以删除它所喜欢的任何顺序的无法访问的对象。

Dispose和Finalize之间的区别

处理和完成的基础知识

调用Dispose方法以加速释放非托管资源,例如数据库句柄,文件句柄,信号量和操作系统分配的其他对象。调用dispose方法来执行清理未使用的内存和稀缺资源(如GDI句柄)所需的代码。简单来说,dispose方法提供对显式内存清理的控制。另一方面,Finalize方法是垃圾收集的一部分,用于在垃圾收集之前对对象执行最终清理操作。简单地说,调用finalize方法来释放对象在被销毁之前所拥有的非托管资源。

调用Dispose和Finalize

可以通过用户代码和实现处理资源的方法的类来显式调用Dispose方法。但是,在垃圾收集器执行清理过程之前,无法释放内存。即使对象的其他引用仍然存在,也可以调用该方法。相反,finalize方法只有在确定最后一个内存对象实例被销毁并且不再存在对该对象的引用之后才能由垃圾收集器调用。执行finalize方法后,将从堆内存中删除该对象。

Dispose和Finalize的实现

从内存中处理对象的过程称为dispose模式,可用于访问非托管资源的对象,因为垃圾收集器无法回收非托管资源。实现“IDisposable”接口以及附加的Dispose(布尔)方法,要求释放非托管资源。当对象的实例在其释放之前被销毁时,执行finalize方法。这是一种非确定性方法,由垃圾收集器自行决定,甚至可能不会发生。在非常必要之前,不应在托管对象上实现它。

处理和完成的性能

使用dispose方法而不是最终确定对象的即时处理要快得多。析构函数在运行时自动转换为finalize方法。当对象离开作用域时,垃圾收集器会自动调用它,这通常发生在该对象的实例被销毁时。 finalize方法的问题在于它是非确定性的,这意味着它不确定何时回收不再通过垃圾收集引用的内存。但是,它可能不会立即释放内存;事实上,它可能永远不会被调用,也不能被明确强制。

Dispose vs. Finalize:比较图表

Dispose与Finalize的摘要

dispose和finalize方法之间的主要区别在于前者是一种确定性方法,可以在不再使用对象时立即对其进行处置,而后者是一种非确定性方法,用于分配非托管资源,这意味着它是一种可以自由获取的后备方法内存对象实例在取消分配之前超出范围。除非非常必要,否则始终建议使用dispose方法而不是最终化。

换句话说,在发生某些编程错误时,如果无法调用dispose方法,则finalize是一个清理非托管资源的安全措施。当一个对象即将从堆内存中踢出时,垃圾收集器会调用Finalize方法。