管理可用资源
公共语言运行库 (CLR) 使用垃圾回收器来管理对象生存期和内存使用。这意味着无法再访问的对象将被垃圾回收器自动回收,并且自动回收内存。由于多种原因无法再访问对象。例如,可 能没有对该对象的任何引用,或者对该对象的所有引用可能来自其他可作为当前回收周期的一部分进行回收的对象。尽管自动垃圾回收使您的代码不必负责管理对象 删除,但这意味着您的代码不再对对象的确切删除时间具有显式控制。请考虑下列原则,以确保您能够有效地管理可用资源:
1)确保在被调用方对象提供 Dispose 方法时该方法得到调用。如果您的代码调用了支持Dispose 方法的对象,则您应该确保在使用完该对象之后立即调用此方法。调用 Dispose 方法可以确保抢先释放非托管资源,而不是等到发生垃圾回收。除了提供 Dispose 方法以外,某些对象还提供其他管理资源的方法,例如,Close 方法。在这些情况下,您应该参考文档资料以了解如何使用其他方法。例如,对于 SqlConnection 对象而言,调用 Close 或 Dispose 都足可以抢先将数据库连接释放回连接池中。一种可以确保您在对象使用完毕之后立即调用 Dispose 的方法是使用 Visual C# .NET 中的 using 语句或 Visual Basic .NET 中的Try/Finally 块。 下面的代码片段演示了 Dispose 的用法。
C# 中的 using 语句示例:
using( StreamReader myFile = new StreamReader("C:\\ReadMe.Txt")){
string contents = myFile.ReadToEnd();
//... use the contents of the file
} // dispose is called and the StreamReader’s resources released
Visual Basic .NET 中的 Try/Finally 块示例:
Dim myFile As StreamReader
myFile = New StreamReader("C:\\ReadMe.Txt")
Try
String contents = myFile.ReadToEnd()
’... use the contents of the file
Finally
myFile.Close()
End Try 注:在 C# 和 C++ 中,Finalize 方法是作为析构函数实现的。在 Visual Basic .NET 中,Finalize 方法是作为 Object 基类上的 Finalize 子例程的重写实现的。
2)如果您在客户端调用过程中占据非托管资源,则请提供 Finalize 和 Dispose 方法。如果您在公共或受保护的方法调用中创建访问非托管资源的对象,则应用程序需要控制非托管资源的生存期。在图 8.1 中,第一种情况是对非托管资源的调用,在此将打开、获取和关闭资源。在此情况下,您的对象无须提供 Finalize 和 Dispose 方法。在第二种情况下,在方法调用过程中占据非托管资源;因此,您的对象应该提供 Finalize 和 Dispose 方法,以便客户端在使用完该对象后可以立即显式释放资源。
垃圾回收通常有利于提高总体性能,因为它将速度的重要性置于内存利用率之上。只有当内存资源不足时,才需要删除对象;否则,将使用所有可用的应用程序资源以 使您的应用程序受益。但是,如果您的对象保持对非托管资源(例如,窗口句柄、文件、GDI 对象和网络连接)的引用,则程序员通过在这些资源不再使用时显式释放它们可以获得更好的性能。如果您要在客户端方法调用过程中占据非托管资源,则对象应该 允许调用方使用IDisposable 接口(它提供 Dispose 方法)显式管理资源。通过实现 IDisposable,对象将通知它可被要求明确进行清理,而不是等待垃圾回收。实现 IDisposable 的对象的调用方在使用完该对象后将简单地调用 Dispose 方法,以便它可以根据需要释放资源。注如果您的可处置对象派生自另一个也实现了 IDisposable 接口的对象,则您应该调用基类的 Dispose 方法以使其可以清理它的资源。您还应该调用实现了 IDisposable 接口的对象所拥有的所有对象上的 Dispose。Finalize 方法也使您的对象可以在删除时显式释放其引用的任何资源。由于垃圾回收器所具有的非确定性,在某些情况下,Finalize 方法可能长时间不会被调用。实际上,如果您的应用程序在垃圾回收器删除对象之前终止,则该方法可能永远不会被调用。然而,需要使用Finalize 方法作为一种后备策略,以防调用方没有显式调用 Dispose 方法(Dispose 和 Finalize 方法共享相同的资源清理代码)。通过这种方式,可能在某个时刻释放资源,即使这发生在最佳时刻之后。注要确保 Dispose 和 Finalize 中的清理代码不会被调用两次,您应该调用GC.SuppressFinalize 以通知垃圾回收器不要调用 Finalize 方法。垃圾回收器实现了 Collect 方法,该方法强制垃圾回收器删除所有对象挂起删除。不应该从应用程序内调用该方法,因为回收周期在高优先级线程上运行。回收周期可能冻结所有 UI 线程,从而使得用户界面停止响应。
相关推荐:
北京 | 天津 | 上海 | 江苏 | 山东 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
广东 | 河北 | 湖南 | 广西 | 河南 |
海南 | 湖北 | 四川 | 重庆 | 云南 |
贵州 | 西藏 | 新疆 | 陕西 | 山西 |
宁夏 | 甘肃 | 青海 | 辽宁 | 吉林 |
黑龙江 | 内蒙古 |