2009-07-01 49 views
1

我有這樣的代碼:如果有其他對象指向它,Dispose可以釋放內存嗎?

public class A: IDisposable 
    { 
     public CPlusCode cPlusCode{get;set;} 

    public void CallB() 
    { 
     using(bCode = new B(cPlusCode)) 
     { 
       //do everything in B 
     } 
    } 

    public void Dispose() 
    { 
     cPlusCode.Dispose(); 
    } 
    } 

    public class B: IDisposable 
    { 
    private CPlusCode cpp; 
     public B(CPlusCode cPlus) 
    { 
    cpp= cPlus; 
    } 
    public void Dispose() 
    { 
    cpp.Dispose(); 
    //dispose everything 
    } 
    } 

    public static void Main() 
    { 
      for(int i=0; i<100000; i++) 
       { 
         var aObject = new A(); 
        aObject .CallB(); 
       } 
    } 

的問題是,當我執行Main,並B消耗了大量的內存實例,並從我的觀察似乎是由程序吃掉內存不釋放。

可以配置真正自由的內存,如果有指向它的其他對象?當它決定它需要,所以「雪中送炭」是不相關的

+0

您可能不應該在B中處理資源,除非它自己創建資源的副本或分配一個新資源。代碼編寫的方式,在同一對象上調用兩次CallB()會導致異常。 – 2009-07-01 07:22:30

回答

2

GC將運行。它發生時會發生;即它是不確定的

6

IDisposable與回收託管內存無關。 IDisposable允許類型的釋放不是由垃圾收集處理資源,如把手等,對於普通的.NET類型,垃圾收集器將負責回收內存當對象不再被引用。

+0

對不起!我編輯的問題,使其更清晰 – Graviton 2009-07-01 07:15:38

0

從我的觀察中看來, 被程序吃掉的內存不是 被釋放了。

這是完全正常的。該程序將掛起一定數量的未使用的內存,如果系統確實需要它,將會釋放該內存。

有人可能會認爲性能最好的事情是保持儘可能小的內存使用量,但實際上是相反的。計算機沒有任何好處,因爲有很多未使用的內存,所以爲了獲得最佳性能,應用程序不應該做額外的工作來最大限度地減少內存使用,直到真正需要它爲止。

可以配置真的釋放內存嗎 還有其他的對象指向 嗎?

是的,沒有...

的對象上調用Dispose不會釋放對象本身,但是如果該對象包含其他對象,這些可以通過Dispose方法來釋放。這本身不會釋放任何內存,但它會讓垃圾收集器在下次運行時執行它。

2

Dispose只是一種方法。它不需要做任何事情。

在對象上調用Dispose後,該對象仍然存在,但無法再安全使用。但是,運行時並不協助執行此操作。 Dispose(一個旨在幫助捕捉錯誤的「固體」實現)會將該對象內的_disposed標誌設置爲true,如果該標誌爲真(該方法本身應該默默忽略,則該對象上的每個其他方法將拋出ObjectDisposedException進一步調用)。但是,實施者完全可以在多大程度上執行這種模式。

一個例子是FileStream。當它有一個打開的文件,進程的句柄計數將增加1。當你調用它Dispose,句柄計數將減少。但是,這僅僅是因爲FileStream作者寫自己Dispose方法來做到這一點。

這導致了一個問題 - 你可以看到在任務管理器的進程的句柄計數,這是一個非常簡單的計數器,但你是如何測量內存使用情況?請注意,任務管理器中顯示的數字遠非直截了當的措施。

+1

我寧願拋出一個ObjectDisposedException,但完全同意其餘的。 http://msdn.microsoft.com/en-us/library/system.objectdisposedexception.aspx – 2009-07-01 08:04:16

0

如果您已經正確實施它,並且您釋放了Dispose()中的所有非託管資源,那麼在您釋放對該對象的所有引用後應該收集該對象(或更好,將有資格收集)。

但是請注意,你是不是在你的榜樣,這也是IDisposable處置對象A。如果A包含對B的引用,並且您不處置A,那麼這也可能會延遲收集B(如果A包含一些可能創建對A的引用的非託管內容)。

由於非託管代碼似乎是在你的榜樣A引用,A應該負責處置它。

相關問題