C#中对象的销毁和内存回收

痞子三分冷 提交于 2020-03-11 18:56:56

在C++中,在堆上分配的内存必须手动回收。即new和delete操作符是要成对使用的。这种方式给程序员提供了强大而灵活的控制能力,程序员可以控制何时销毁对象,回收内存 。这种控制能力,令C++程序员感到自己对程序具有很强的驾驭能力,因此对此功能津津乐道。但是,这种手动回收机制,非常的难以控制,即使经验丰富的C++程序员,也难免疏漏,导致程序中发生内存泄露,轻则导致系统运行越来越慢,重则最终崩溃。这也是手动回收机制所最为人所诟病的地方。

因此,在很多所谓的现代程序语言中,如Java,C#,都提供了自动垃圾回收机制。在对象不再被引用后,系统自动负责销毁对象,回收内存。在托管C++中,通过语言扩展,也可以实现垃圾的自动回收。

自动垃圾回收无需程序员的干预,自动回收废弃对象,释放内存。它有效的避免了内存泄露问题,但是,相应的也带来了新的问题: 1、废弃对象的回收时间是不确定的,即你无法确定系统在何时会执行垃圾回收。每个垃圾收集器都会按照一定的算法执行垃圾收集,但它何时执行,每次执行回收哪些对象是不确定的。 2、它使程序员丧失了部分的控制能力,相应的在系统运行过程中,在性能上也会有一定的损失。

C#中对象的销毁和回收,在实现方式上比较灵活。它既允许立刻销毁对象,回收内存,也允许通过垃圾回收器自动回收。能够做到这点,是因为C#提供了两种对象的销毁方式:

1、类支持IDisposable接口,在每次使用完对象后,立即通过手工Dispose()方法,或者利用Using块隐式的强制调用Dispose()方法,实现在对象的立即销毁。在Dispose()方法中,将调用Dispose()方法的带一个布尔参数的重载,在该重载函数中,手工编写代码释放对象所打开的所有托管和非托管资源。

2、通过垃圾回收器自动回收,在垃圾回收器销毁对象的时候,调用类的析构函数,释放对象打开的非托管资源,销毁对象,回收内存。由于析构函数仅在使用垃圾回收器回收的时候调用,因此析构函数内仅需要释放非托管资源即可,对象所打开占用的托管资源对象,会被垃圾回收器自动销毁。析构函数对非托管资源的释放,也是通过调用调用Dispose()方法的带一个布尔参数的重载来实现。

通过上面的描述可见,在C#类中,真正释放资源的操作代码,都是在Dispose()方法的带一个布尔参数的重载中。Dispose()和析构函数,都是通过调用该重载来释放资源。这种方式,保证了所有与释放资源有关的代码都集中在一个函数中,便于维护。

这种既允许立即销毁对象,又允许通过垃圾收集器自动回收的实现方式,充分的体现了C#的灵活性,我觉得是C#功能强大的体现之一。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!