IronPython的致命弱点

IronPython到最后还是编译为IL代码被执行了,这其中用到了动态生成程序集的技术。

然而,这个动态生成的程序集是需要在某个AppDomain中被定义的,因此,不可避免的要在AppDomain中加载这个程序集。众所周知,Assembly无法单独地从AppDomain卸载,要卸载某个Assembly,必须将它所在的AppDomain卸载。很遗憾的是,IronPython中动态生成的程序集是在程序主域中定义,也就是说,如果程序不退出,动态生成的Assembly将一直存在,最终导致内存泄漏。

让人无可奈可的是,这不仅仅是IronPython的问题,而且是整个CLR的硬伤(针对微软今后要主推的WPF)。假设要做一个插件体系的软件,按照微软的建议,我们应该在单独的AppDomain中加载插件所需的程序集,在卸载插件的时候卸载掉这个AppDomain。然而,有时候我们需要插件提供一个视图,结果WPF的控件不是从MarshalByRefObject继承而来,也就是说,它们不允许跨域的操作。为此,我们不得不把这些包含视图的程序集加载到主AppDomain中,后果就是持续的Memory Cost。

其实,微软自己也在尝这个苦果,看看.Net 3.5提供的AddIn,里面不得不用一些Adapter来实现WPF控件的跨域操作,然而控件的事件传递无法实现,而且程序经常会Crash。

当然,我们可以说,只要关闭了程序,资源就会被释放了,但恰恰有些项目是有上千个甚至上万个这样需要提供视图的Assembly(考虑一下银行的交易系统),而这些应用程序是跑在24x7无间断运行终端上的,这个问题的影响就相当严重了。

原文地址:https://www.cnblogs.com/RMay/p/1323580.html