Expression<TDelegate>.Compile和垃圾回收

13

当我将表达式编译成可执行代码并获取委托时,当不再存在对该委托的引用时,该代码是否会被垃圾收集?

这方面有文档吗?因为我在MSDN中没有找到有用的信息。

1个回答

15
是的,代码可以进行垃圾回收。当您在T表达式上调用Compile时,代码将被编译成DynamicMethod,这些方法可进行垃圾回收。
实际上,MSDN上没有说明,但您可以查看DLR中Expression<T>.Compile的实现,这是.net 4.0的发行版本:

http://dlr.codeplex.com/SourceControl/changeset/view/54115#990638

尽管在 .net 3.5 中编译器的实现不同,但仍然使用了 DynamicMethods(来源:我自己,在 Mono 中实现了 System.Linq.Expressions)。
当您使用 Expression<T>CompileToMethod 并且传递一个来自未使用 RunAndCollect 标志创建的 AssemblyBuilder 的 MethodBuilder 时,编译的表达式树不可回收。

使用DynamicMethod足够吗?根据Eric提供的链接http://msdn.microsoft.com/en-us/library/dd554932.aspx,程序集需要使用特殊标志进行创建。在Reflector中,我可以看到DynamicMethod.GetDynamicMethodsModule()方法不会使用RunAndCollect而是只使用Run来创建程序集。 - Alex Shtof
是的,动态方法足够了,在MSDN中有说明。 动态方法在CLR中具有特殊处理,并且确实可收集。 - Jb Evain
是的,我现在可以在DynamicMethod类的文档中看到它。谢谢 :) - Alex Shtof
我的理解也是如此。这很奇怪,我想知道“可收集程序集”的意义是什么。 - Hans Passant
DynamicMethod来自.net 2.0,当时没有RunAndCollect。 它们在运行时具有特殊处理,并且匿名方法绑定到新模块。 RunAndCollect程序集是在.net 4.0中新增的,范围显然比简单方法广得多。 - Jb Evain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接