新地址来更新,但垃圾收集器会处理更新问题。
到目前为止,windows平台已经使用了两种技术来释放进程向系统动态请求的内存:
1:完全以手工方式使应用程序代码完成这些工作(C++)。
2:让对象维护引用计数。(com计数)
托管代码定义
以运行库为目标的代码称为托管代码
C++分成两种,一种是托管C++,另外一种是非托管C++
C#是以运行库为目标设计的,因此用C#编写的代码基本上为托管代码
不以运行库为目标的代码称为非托管代码
.NET提供了与非托管代码互操作的服务,比如与COM互操作的Interop服务
.NET平台在内存管理方面提供了GC(Garbage Collection),负责自动释放托管资源和内存回收的工作,但它无
法对非托管资源进行释放,这时我们必须自己提供方法来释放对象内分配的非托管资源,比如你在对象的实现代
码中使用了一个COM对象。
最简单的办法,可以通过实现protected void Finalize()来释放非托管资源,因为GC在释放对象时会检查该对
象是否实现了Finalize()方法,如果是则调用它。但这样会降低效率……
有一种更好的,那就是通过实现一个接口显式的提供给客户调用端手工释放对象的方法,而不是傻傻的等着GC来
释放我们的对象(何况效率又那么低)。
System 命名空间内有一个 IDisposable 接口,拿来做这事非常合适,就省得我们自己再声明一个接口了。
另外,这种实现并不一定要使用了非托管资源后才用,如果你设计的类会在运行时有大些的实例(像GIS 中的
Geometry),为了优化程序性能,你也可以通过实现该接口让客户调用端在确认不需要这些对象时手工释放它们
。
实现过程
![](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
using System;
using System.Collections.Generic;
using System.Text;
namespace Example20
{
class Program
{
class Class1 : IDisposable
{
//析构函数,编译后变成 protected void Finalize(),GC会在回收对象前调用该方法
Class1()
{
Dispose(false);
}
//通过实现该接口,客户可以显式地释放对象,而不需要等待GC来释放资源,据说那样会降低效率
void IDisposable.Dispose()
{
Dispose(true);
}
//将释放非托管资源设计成一个虚函数,提供在继承类中释放基类的资源的能力
protected virtual void ReleaseUnmanageResources()
{
//Do something
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
}
//私有函数用以释放非托管资源
private void Dispose(bool disposing)
{
ReleaseUnmanageResources();
//为true时表示是客户显式调用了释放函数,需通知GC不要再调用对象的Finalize方法
//为false时肯定是GC调用了对象的Finalize方法,所以没有必要再告诉GC你不要调用我的
Finalize方法
if (disposing)
{
//清理托管的代码
GC.SuppressFinalize(this);//请求对象不要调用指定的对象的终结器
}
}
}
static void Main(string[] args)
{
//tmpObj1没有手工释放资源,就等着GC来慢慢的释放它
Class1 tmpObj1 = new Class1();
//tmpObj2调用了Dispose方法,比等着GC来释放它效率要高一些
Class1 tmpObj2 = new Class1();
((IDisposable)tmpObj2).Dispose();
}
}
}
总结的就是这些了!