1、C#幾乎所有對象都為托管對象,不同點是有的對象封裝了非托管資源。
2、C#大部分對象在進行垃圾回收時都可以回收,包括非托管資源,因為非托管資源都已經通過C#類進行了封裝,會將非托管資源的釋放放在析構函數中,同時會實現IDipose接口。
3、IDipose作用是可以通過using手動提前釋放,節約寶貴的資源。
4、在C#中,凡是繼承了IDisposable接口的類,都可以使用using語句,從而在超出作用域后,讓系統自動調用Dispose()方法。 一個資源安全的類,都實現了IDisposable接口和析構函數。提供手動釋放資源和系統自動釋放資源的雙保險。
5、類似FileStream,會同時實現IDipose,及定義~FileStream(),~FileStream()作用是使用者沒有調用IDipose,在GC回收時再回收非托管資源,否則非托管資源只有在程序停止之后才會釋放。
析構函數只能由垃圾回收器調用。Despose()方法只能由類的使用者調用。
總結區分托管資源和非托管資源
(1)托管資源一般是指被CLR控制的內存資源,這些資源的管理可以由CLR來控制,例如程序中分配的對象,作用域內的變量等。
(2)非托管資源是CLR不能控制或者管理的部分,這些資源有很多,比如文件流,數據庫的連接,系統的窗口句柄,打印機資源 等,這些資源一般情況下不存在於Heap(內存中用於存儲對象實例的地方)中。
托管資源:從文字上看就是托付給別人管理,就像.NET的CLR,java的jvm
例子:
public class SourceManager : IDisposable { private bool disposed = false; //非托管資源 private IntPtr handle; //托管資源 FileStream fs = null; public SourceManager() { } //由垃圾回收器調用,釋放非托管資源 ~SourceManager() { //GC調用,終結 Dispose(false);// 釋放非托管資源 } //實現接口方法 //由類的使用者,在外部顯示調用,釋放類資源 public void Dispose() { Dispose(true);// 釋放托管和非托管資源 //將對象從垃圾回收器鏈表中移除, // 從而在垃圾回收器工作時,只釋放托管資源,而不執行此對象的析構函數 GC.SuppressFinalize(this); } //參數為true表示釋放所有資源,只能由使用者調用 //參數為false表示釋放非托管資源,只能由垃圾回收器自動調用 //如果子類有自己的非托管資源,可以重載這個函數,添加自己的非托管資源的釋放 //但是要記住,重載此函數必須保證調用基類的版本,以保證基類的資源正常釋放 protected virtual void Dispose(bool disposing) { // 如果資源未釋放 這個判斷主要用了防止對象被多次釋放 if (!this.disposed) { if (disposing && fs != null) { // 釋放托管資源 fs.Dispose(); } //釋放非托管資源 //... handle = IntPtr.Zero; disposed = true; // 標識此對象已釋放 } } }