2009-11-09 43 views
5

很多年前,我被告誡,只要有可能,就會按照與分配方式相反的順序釋放資源。那就是:C#:按照分配的相反順序處理資源是否有優勢?

block1 = malloc(...); 
block2 = malloc(...); 

... do stuff ... 

free(block2); 
free(block1); 

我想象一個640K的MS-DOS機器上,這可以最小化堆碎片。在C#/ .NET應用程序中做這件事有沒有實際的好處,或者這是否已經超過了它的相關性?

回答

5

如果你的資源創造得很好,這應該不重要(很多)。

但是,很多創建不好的庫並沒有做適當的檢查。將資源分配到與其分配相反的位置通常意味着您首先處理依賴於其他資源的資源 - 這可以防止寫得不好的庫導致問題。 (你永遠不會處理一個資源,然後使用一個取決於第一個存在的資源)

這也是一個很好的做法,因爲你不會意外地處理一些其他對象所需的資源太早。

下面是一個示例:查看數據庫操作。在關閉/處理您的命令(使用連接)之前,您不想關閉/處理連接。

+0

創建好並不好。它必須是順序依賴的,在許多情況下依賴於釋放並且是已知的。在數據庫,事務和任何在棧上運行的任何實現(大多數軟件)中,都無關緊要。鎖是另一個例子,並且有一堆使用它的非外部和非窮人的庫。文件操作和他們的鎖是另一個。另一個事件泄漏。任何非託管資源取決於另一個。創造和毀滅是並存的,這個成語不能被認爲是資源初始化 - 「良好創造」。 – 2009-11-09 20:13:17

+0

因此,RIIWC矛盾中的WC被替換爲Aquisition,這意味着一個Release btw。而且,由於內存和大量的資源大部分都是抽象的,操作系統,這個想法......以及各種各樣的黑客隨之而來。簡而言之,這只是問題的本質,而且它很重要。 – 2009-11-09 20:14:14

+0

雖然我在這裏並沒有捍衛順序依賴,但正確的觀察是,它非常重要,但很少需要。但即使VM的官方規範極其受限制,也是如此。尤其是Java impl和CLR在一個較小但仍然很重要的程度上。不要破壞大量的工作代碼和假設,編譯器和jit後端設計者做出明智的決定。能夠進行順序無關處理的代碼適用於大量可能性,但對於大量場景可能不可行。 – 2009-11-09 20:25:08

4

不要打擾。 GarbageCollector保留對堆進行碎片整理和移動對象的權利,因此不知道事情是以什麼順序進行的。

另外,如果您要處置A和B以及A引用B,那麼應該無關緊要在處理A時處置B,因爲Dispose方法應該可多次調用而不會引發異常。

+1

真,只要你不使用「處置「通過意外引用(通過從它創建的另一個對象),因爲你在任意ord中進行處理呃。 – 2009-11-09 19:40:10

0

嵌套的'使用'表明你'生命'並不真正開啓,而且很少是(不要在40年的證據之後說永遠不要說)。這包括基於堆棧的虛擬機,它運行在CMOS 。

儘管MSDN.com和Duffius試圖讓它消失,但你知道爲你管理堆和堆棧之間的差異。多麼聰明的主意......在太空中]

1

如果您指的是對象上的析構函數被調用的時間,那麼這就是垃圾回收器,編程對此沒有什麼影響,並且根據語言定義它是非確定性的。

如果您指的是調用IDisposable.Dispose(),則取決於實現IDisposable接口的對象的行爲。

一般來說,大多數Framework對象的順序並不重要,除非它對調用代碼有影響。但是,如果對象A保持對對象B的依賴關係,並且對象B被處理,那麼重要的是不要與對象A做某些事情。

在大多數情況下,Dispose()不直接調用,但相反,它被隱式地稱爲using或foreach語句的一部分,在這種情況下,根據嵌入語句,反序模式自然會出現。

using(Foo foo = new Foo()) 
using(FooDoodler fooDoodler = new FooDoodler(foo)) 
{ 
    // do stuff 
    // ... 
    // fooDoodler automatically gets disposed before foo at the end of the using statement. 
} 
0

「運行時不作任何保證,而在最終確定方法調用的順序。例如,假設有一個包含一個指向內對象的對象。垃圾收集器檢測到兩個對象都是垃圾。此外,說內部對象的Finalize方法被首先調用。現在,允許外部對象的Finalize方法訪問內部對象並調用它的內部對象,但內部對象已完成並且結果可能不可預知。出於這個原因,強烈建議finalize方法不能訪問任何內部,成員對象。」

http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

所以你可以不用擔心你的後進先出法處置語義儘可能多的,只要你喜歡,但如果您泄漏之一,Dispose()方法的要在任何順序CLR幻想被調用。

(這是多了還是少了什麼威爾說,以上)

相關問題