对象生存期:如何创建和销毁对象

当使用 New 关键字创建类的实例时,对象便产生。在首次使用新对象前通常要求执行初始化任务。通用初始化任务包括打开文件、连接到数据库和读取注册表项的值。Microsoft Visual Basic .NET 使用称为构造函数的过程控制新对象的初始化。

在对象出了范围并由公共语言运行库 (CLR) 释放后,对象即告消亡。Visual Basic .NET 使用称为“析构函数”的过程控制系统资源的释放。“构造函数”(允许控制初始化的特殊方法)和“析构函数”一起支持可靠且可预知的类库的创建。

Sub New 和 Sub Finalize

Visual Basic .NET 中的 Sub NewSub Finalize 过程初始化和销毁对象。它们替换了 Visual Basic 早期版本中使用的 Class_InitializeClass_Terminate 方法。与 Class_Initialize 不同,Sub New 构造函数只能在创建类时运行一次,且除了从同一类或派生类的另一个构造函数代码的第一行以外,不能在别的任何地方显式调用它。另外,Sub New 方法中的代码总是在类中其他任何代码之前运行。如果没有为类显式定义 Sub New 过程,则 Visual Basic .NET 会在运行时隐式创建一个 Sub New 构造函数。

在释放对象之前,CLR 会为定义了 Sub Finalize 过程的对象自动调用 Finalize 方法。Finalize 方法可以包含恰在对象销毁前需要执行的代码(如关闭文件和保存状态信息)。执行 Sub Finalize 会有轻度的性能降低,所以应当只有在需要显式释放对象时才定义 Sub Finalize 方法。

Finalize 析构函数是只能从其所属类或派生类调用的受保护方法。当销毁对象时系统自动调用 Finalize,所以不应该从派生类的 Finalize 实现的外部显式调用 Finalize。与 Class_Terminate 不同(Class_Terminate 在对象设置为无效后立刻执行),在对象丧失范围和 Visual Basic .NET 调用 Finalize 析构函数之间通常会有延迟。Visual Basic .NET 还允许另一种析构函数 Dispose,该函数可以在任何时候显式调用以立即释放资源。

IDisposable 接口

类实例通常控制那些不由 CLR 管理的资源,如 Windows 句柄和数据库连接。为补充垃圾回收,如果类实现了 IDisposable 接口,则类可以提供一种机制来活动地管理系统资源。IDisposable 有一种方法名为 Dispose,当客户端结束对对象的使用时应当调用此方法。可以使用 Dispose 的实现来释放资源并执行诸如关闭文件和数据库连接之类的任务。与 Finalize 析构函数不同,Dispose 方法不会自动调用。当需要释放资源时,类的客户端必须显式调用 Dispose

垃圾回收和 Finalize 析构函数

.NET Framework 使用名为“引用跟踪垃圾回收”的系统,该系统定期释放未使用的资源。Visual Basic 的早期版本使用名为“引用计数”的另一个系统来管理资源。虽然这两个系统自动执行同样的功能,但还是有一些重要差异。

当系统确定对象不再需要时,CLR 便定期销毁这些对象。当系统资源短缺时,对象释放会快一些,否则就不那么频繁。在对象丧失范围和 CLR 释放对象之间的延迟意味着您不能准确确定对象将在什么时候销毁,这与 Visual Basic 的早期版本中对象的情况不同。在此类情况下,称对象具有“非确定性生存期”。在大多数情况下,非确定性生存期并不会对您如何编写应用程序产生影响,只要您记住 Finalize 析构函数可能不会在对象丧失范围时立即执行即可。

这两个垃圾回收系统之间的另一个差异涉及到 Nothing 的使用。为了利用引用计数,使用 Visual Basic 早期版本的程序员有时将 Nothing 分配给对象变量以释放那些变量所保存的引用。如果变量保存的是对对象的最后一个引用,对象的资源将立即被释放。在 Visual Basic .NET 中,尽管可能存在此过程仍然有价值的情况,但执行此分配从不会导致被引用对象立即释放其资源。只有当变量生存期相对于垃圾回收器检测孤立对象所需时间较长时才应当将变量设置为 Nothing

请参见

posted on 2006-07-25 09:39  zman   阅读(892)  评论(0编辑  收藏  举报

导航