• 为什么.Net平台不支持程序集卸载(Assembly.Unload)?


    我们知道在.net平台中反射提供了在运行时动态的获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象。我们知道反射中可以通过System.Reflection.Assembly命名空间下的 Assembly.Load 动态的加载程序集信息,获取我们想要的一切信息。那么当我们动态加载完程序集并对其使用完之后,我们想卸载掉它,不想在内存中留下垃圾信息,这时我们发现Assembly并没有提供Assembly.UnLoad的方法让我们动态的卸载程序集,这是为什么呢?

    首先我们之所以要实现 Assembly.Unload 函数,主要是为了回收空间和更新版本两类需求。前者在使用完 Assembly 后回收其占用资源,后者则卸载当前版本载入更新的版本。例如 ASP.NET 中对页面用到的 Assembly 程序的动态更新就是一个很好的使用示例。但如果提供了 Assembly.Unload 函数会引发下面的一些问题:

    1.为了保证CLR 中代码所引用的代码地址都是有效的,必须跟踪诸如 GC 对象和 COM CCW 之类的特殊应用。否则会出现 Unload 一个 Assembly 后还有 CLR 对象或 COM 组件使用到这个 Assembly 的代码或数据地址,进而导致访问异常。而为了避免这种错误进行的跟踪,目前是在 AppDomain 一级进行的,如果要加入 Assembly.Unload 支持,则跟踪的粒度必须降到 Assembly 一级,这虽然在技术上不是不能实现,但代价太大了。

    2.如果支持 Assembly.Unload 则必须跟踪每个 Assembly 的代码使用到的句柄和对现有托管代码的引用。例如现在 JITer 在编译方法时,生成代码都在一个统一的区域,如果要支持卸载 Assembly 则必须对每个 Assembly 都进行独立编译。此外还有一些类似的资源使用问题,如果要分离跟踪技术上虽然可行,但代价较大,特别是在诸如 WinCE 这类资源有限的系统上问题比较明显。

    3.CLR 中支持跨 AppDomain 的 Assembly 载入优化,也就是 domain neutral 的优化,使得多个 AppDomain 可以共享一份代码,加快载入速度。而目前无法处理卸载 domain neutral 类型代码。这也导致实现 Assembly.Unload 完整语义的困难性。

    基于上述的愿意目前并不支持动态的卸载程序集信息。

    想了解更详细的原因可参考大神的博客:https://blogs.msdn.microsoft.com/jasonz/2004/05/31/why-isnt-there-an-assembly-unload-method/

  • 相关阅读:
    97. 交错字符串-7月18日
    如何判断一个区块链项目的好坏?
    不知道这10点,千万别用SaaS
    数字人民币应用的五大猜想!你最关心哪个?
    什么是人工智能核心?这2个功能上线
    大数据的七大核心具体价值
    机器学习操作正在兴起
    每个大数据架构师都需要的6个基本技能
    数据之美:可视化会给你意想不到的答案!
    如何采用人工智能创建自动化运营的数据中心
  • 原文地址:https://www.cnblogs.com/Wolfmanlq/p/7148075.html
Copyright © 2020-2023  润新知