Dispose, Finalization, and Resource Management

简介:

原文见:DG Update: Dispose, Finalization, and Resource Management

*Explicit Cleanup & Implicit Cleanup

*实现Finalizer的类,无可避免地加大了系统的负担。最小的开支来自于,至少要把这个对象,加入Finalizable Object列表。

 

Dispose Pattern:

Do implement the dispose pattern when your type is unsealed and contains resources that explicitly need to be or can be freed.

Do fully implement the dispose pattern on classes with disposable subtypes, even if the base type does not own resources.(eg. Stream)

Do implement IDispoable only on classes where a class in its parent hierarchy has not already done so.

*GC.SuppressFinalizer(this)应该放在Dispose(true)之后。

Do create or override the protected irtual void Dispose(bool disposing) method to encapsulate all of your cleanup logic.

这个虚方法的参数bool值表示是Explicit Cleanup还是Implicit Cleanup。因为如果是Implicity CleanUp,则表示是因为GC引起的调用,所以这时,代码最好不要使用类型中的引用类型字段。

Do make a call to your base class’s Dispose(bool disposing) method (if available) as the last operation in your Dispose(bool) implementation.

Do implement a finalizer if your object is responsible for controlling the lifetime of at least one resource which does not have its own finalizer.

Do not re-implement the IDisposable interface, override void Dispose(), or override Finalize if a base type in your class hierarchy has already defined them according to this pattern.

Do not create any other variations of the Dispose method other than the two specified here: void Dispose() and void Dispose(bool disposing).

 

Dispose

Do implement IDisposable on every type that has a finalizer.

Do allow your Dispose method to be called more than once.

Do transitively dispose of any disposable fields defined in your type from your Dispose method.

Consider setting disposed fields to null before actually executing dispose when reference cycles in an object graph are possible.

Avoid throwing an exception from within Dispose except under critical situations where the containing process has been corrupted(leaks, inconsistent shared state, etc.).

Consider making your object unusable after calling Dispose.

Do implement a Close method for cleanup pruposes if such terminology is standard, for example as with a file or socket.

Consider nulling out large managed object fields in your Dispose method.

Avoid createing disposable value types, and never create a value type which manages the lifetime of unmanaged resources disrectly.

Consider disposing of any IDisposable object instances when your are done with them.

Do not swallow exceptions arising from a call to Dispose.

 

Finalization

Do carefully consider any case where you think a finalizer is needed.

Do make your Finalize method protected, not public or private.(C#/C++ developers do not need to worry about this.)

Do free only owned unmanaged resources in your type’s Finalize method.

Do not directly call the Finalize method.

Do gracefully handle situations in which your finalizer is invoked more than once.

Do not assume your object is unreachable during finalization.

Do not assume your finalizer will always run.

Consider using a critical finalizable object(SafeHandle, or any type whose type hierarchy contains CriticalFinalizerObject) for situations where a finalizer absolutely must execute even in the face of AppDomain unloads and rude thread aborts.

Avoid allocating memory in finalizers.

Do not allocate memory from within a critical finalizer, ofr from SafeHandle’s ReleaseHandle method, at least not on the success paths.

Do not call virtual members from finalizers except for in very controlled designs, such as the Dispose(bool) method outlined in the pattern above.

Do write finalizers that are tolerant of partially constructed instances(i.e. objects whose constructors may have never completed).

Do write finalizers that are threading-agnostic.

Avoid blocking execution from within a finalizer.

Do not raise unhandled exceptions or otherwise leak exceptions from your finalizer, except for in very system critical circumstances(such as OutOfMemory, for example).

Avoid resurrecting yourself by setting a reference to a rooted context, i.e. through a GC reachable reference such as a static field or reachable objects to which you still have a reference.

Do not assume that avoiding resurrecting yourself prevents you from being rooted again after or during finalization.

Do not modify thread context from within your finalizer, as it will end up polluting the finalizer thread.

Do not assume that, because some object is reachable while you’re being finalized, that it has not been or is not in the process of being finalized-e.g., static fields, common infrastructure, and so on.

Do not define finalizers on value types.

 

SafeHandle

Do use SafeHandle for warpping scarce unmanaged resources such as OS handles, preferring it to IntPtr or Int32 representations for native handles.

 

HandleCollector and Memory Pressure

Avoid making calls to GC.Collect() and GC.GetTotalMemory(true) with the intent of controlling the GC’s policy to provoke collecting resources eagerly.

目录
相关文章
|
17天前
|
NoSQL 编译器 API
关于thread使用的错误:pure virtual method called terminate called without an active exception
关于thread使用的错误:pure virtual method called terminate called without an active exception
11 1
|
6月前
|
Web App开发 前端开发
【前端异常】Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
【前端异常】Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
458 0
|
7月前
|
Java
“Resource leak: ‘sc‘ is never closed”的解决及解释
“Resource leak: ‘sc‘ is never closed”的解决及解释
190 0
|
9月前
|
消息中间件 Java RocketMQ
【Java】Error creating bean with name ‘functionBindingRegistrar‘ defined in class path resource的一种解决方式
【Java】Error creating bean with name ‘functionBindingRegistrar‘ defined in class path resource的一种解决方式
51 0
BeanFactory not initialized or already closed - call 'refresh' before access
BeanFactory not initialized or already closed - call 'refresh' before access
172 0
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
在main函数中创建新对象时出错 No enclosing instance of type ooo is accessible. Must qualify the allocation with a
|
JavaScript 前端开发
UI5 Control lazy load mechanism
Create dummy constructor which loads the class on demand this is a derived ( generated ) file. Change should be done in the underlying source files only(*.control, *.js) or they will be lost after the next generation.
114 0
UI5 Control lazy load mechanism
cannot load SAP UI5 application view S2 useful method for resource load
cannot load SAP UI5 application view S2 useful method for resource load
cannot load SAP UI5 application view S2 useful method for resource load
|
MySQL 关系型数据库 PHP
请手动释放你的资源(Please release resources manually)
作者: Laruence(   ) 本文地址: http://www.laruence.com/2012/07/25/2662.html 转载请注明出处 我从来不认为这个问题是个问题, 直到昨天.
1006 0