2010-09-30 57 views
1

我們正在使用自定義RuntimeDataBuilder類,它使用Reflection.Emit爲我們從泛型WCF DataService接收到的信息創建簡單的屬性獲取器/設置器,從而動態地構造內存中的.NET類型。該服務公開了由1..m DataTableDefinitions組成的「DataSet like」結構,每個DataTableDefinitions都包含1..m DataTableColumnDefinitions。當接收到客戶端信息時,我們使用其屬性設置器/獲取器生成類型,以提高性能並促進綁定到我們的Silverlight客戶端。所有這些工作正常。MSIL內存泄漏

我的問題是與可能的內存泄漏有關的再生類型。有時用戶可以更改查詢參數,這可能會導致更多/更少的信息通過線路。因此它使我們創建的以前的類型無效,並且我想確保我們能夠釋放此前類型定義所使用的內存。我從this article on MSDN瞭解到,如果您使用輕量級代碼生成(LCG),代碼將分配到託管堆上,當GC沒有任何引用時,將由GC回收這些代碼。但LCG似乎只適用於動態方法。我擔心的是現在不再需要所有屬性獲得者/設置者的類型。如果這是在非託管堆上分配的,我們唯一希望回收內存的方式似乎是確保將該類型加載到臨時AppDomain中,以便在不再需要時可以卸載該臨時AppDomain。

有人可以確認或突出顯示回收內存的另一種方式。

THX

回答

4

你在想,動態類型將留在記憶一旦被加載到一個AppDomain正確的。正如您所說,能夠從Process中卸載它們的唯一方法是將它們託管在一個單獨的AppDomain中,然後您可以將其全部卸載。但是你必須小心,即使在那裏:確保對Type的引用不會泄漏到你的主AppDomain中,否則這些將導致它留在內存中。

CLR黎明有兩個鏈接,您可能會發現有用:Unloading an AssemblyWhy isn't there an Assembly.Unload method?。您是否看過DLR?這可能是像ExpandoObject可以幫助你,儘管它看起來像目前不支持數據Silverlight 4綁定(也許in Silverlight 5?)

+0

ExpandoObject當然是一個選項,但正如您提到的SL4中不支持的那樣。 Thx雖然確認。 – Carel 2010-10-01 04:40:28

3

.NET 4.0引入了collectible assemblies概念,是符合垃圾回收。使用示例可以在here找到。

+0

不幸的是,Silverlight目前不支持可收集的程序集,這是問題發生的地方(我推斷這種缺乏支持,因爲Silverlight 4文檔中的AssemblyBuilderAccess枚舉中缺少必要的RunAndCollect標誌:http://msdn.microsoft。 com/en-us/library/2e88sa1d(v = VS.100).aspx) – 2010-09-30 20:58:58

+0

這很傷心。在這種情況下,生成的程序集將保留在內存中,並且只有在包含AppDomain時纔會被卸載。 – desco 2010-09-30 21:03:52

+0

不知道收集的組件。很高興知道它的存在。不幸的是,它不支持SL。 – Carel 2010-10-01 04:42:05