2013-05-15 68 views
0

假設我有一個很大的Image對象,如果我調用此對象的Dispose()方法,我可以很容易地看到我的應用程序的內存消耗減少了,因爲我只是從內存中清除了對象。如果我有我自己的類型/類,並且想要處理它的一個實例,比方說,它包含一個byte[]數組(我認爲它與內部類Image類似)。我將如何去執行IDisposable,所以當Dispose()被稱爲byte[]立即從內存中丟棄。沒有我不得不等待GC如何使用Dispose()方法處理某些類型的圖像

如果是string而不是byte[]會怎麼樣?

+0

如果你想知道在調用Dispose方法時你是否可以像這樣((IDisposable)someObject),那麼你不能只聲明你的Class就像'class SomeClass:IDisposable'一樣。 ()';通常如果它實現IDisposable它將正確處置通常你可以確定,即使在設計/編譯時,因爲如果它不會,你會得到一個錯誤 – MethodMan

+0

是的,我可以。但是我應該在Dispose()裏面放置什麼內容才能立即處理我的變量的內容,就像'Image'類一樣? –

+0

對於不執行'IDisposable'的項目,如果你沒有調用'GC',那麼將Object的'value =設置爲null',你也可以用'using(){}'語句包裝代碼 – MethodMan

回答

2

內存消耗在兩種情況下降低:

  1. 垃圾收集器釋放了存儲器中,並且被執行
  2. 非託管代碼已瞬間釋放了存儲器。

圖像數據示例是第二種情況。圖像由OS保存,當您處理圖像時,會調用操作系統釋放圖像緩衝區。這是操作系統的工作,因爲操作系統是在屏幕上顯示圖像的,然後取決於硬件和驅動程序。除此之外,圖形操作系統經過了極大的優化,可以與圖像數據一起工作 - 這一點也不奇怪,它在需要時用於處理圖像。

當您創建自己的一次性課程時,情況完全相反。關於內存佔用情況,執行dispose實際上什麼也不做。即使垃圾收集不會減少內存使用量,只要存在指向已處理類的活動指針即可。

只有當它分配一些非託管資源 - 文件句柄,圖像,套接字(從OS角度來看,這只是一種文件句柄)等時,類才應該實現IDisposable。Dispose方法應該只釋放非託管資源資源。將字段設置爲null並執行類似的傻事毫無意義。

2

.NET中的對象只有存在某種引用時才存在。不存在的對象不保存對任何東西的引用。如果在垃圾收集週期中發現對象沒有任何引用,除了WeakReference目標,系統將使這些對象無效,於是對象將不再有任何指向它們的引用並因此不再存在。如果對某個對象的唯一非弱引用位於已註冊方法的系統的對象列表中,則該對象將從該列表中刪除並添加到系統的應該在第一時間運行該方法的對象列表中。一旦系統運行一個對象的方法Finalize,它將從後面的列表中刪除,除非引用已被存儲在其他地方,它將不再存在。

Image有一個dispose方法的原因是它的構造經常要求創建不是.NET對象的東西和/或要求外部實體代表它做事情(例如授予對文件的獨佔讀訪問權) 。如果一個Bitmap被放棄而沒有調用Dispose,並且如果它沒有Finalize方法,則Bitmap對象將不復存在,但其所請求創建的任何外部對象將繼續存在,並且任何外部實體代表它行事將繼續這樣做。

因爲創建一個字節數組並不需要構造任何不是.NET對象的東西,也不需要任何外部實體代表它做任何事情,所以不需要一個數組不再需要做任何事情,除了不再存在。對於擁有這種陣列的物體也是如此。

相關問題