2010-09-30 103 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