第三节:卸载AppDomain
2024-08-31 02:31:11
AppDomain很出色的一个能力就是它允许卸载。卸载AppDomain会导致CLR卸载AppDomain中的所有程序集。还会释放AppDomain的Loader堆。为了卸载一个AppDomain,可调用AppDomain的静态方法Unload。这将导致CLR执行一系列操作来得体的卸载指定AppDomain。
- CLR挂起进程中执行过托管代码的所有线程。
- CLR检查所有线程栈,查看那些线程正在执行要卸载的那个AppDomain中的代码,或者那些线程会在某个时候返回至要卸载的那个AppDomain。在任何一个栈上,如果有准备卸载的AppDomain,CLR会强迫对应的线程抛出一个ThreadAbortException异常(同时恢复线程的执行)。这将导致线程展开,在展开的过程中执行遇到的所有finally块中的内容,以执行资源清理代码。如果没有代码捕捉ThreadAbortException,它最终会成为一个未处理的异常,CLR会“吃掉”这个异常;
线程会终止,但进程可继续运行。这一点是非常特别的,因为对于其他所有未处理的异常,CLR都会终止进程。
- 当第2步发现的所有线程都离开AppDomain后,CLR遍历堆,为引用了”由已卸载的APPDomain创建的对象”的每一个代理对象都设置一个标志。这些代理对象现在知道他们引用的真实对象已经不在了。如果任何代码在一个无效的代理对象上调用一个方法,该方法会抛出一个AppDomainUnloadedException。
- CLR强制垃圾回收,对现已卸载AppDomain创建的任何对象占有的内存进行回收。这些对象的Finalize方法被调用,使对象有机会彻底清理他们所占用的资源。
- CLR恢复剩余所有线程的执行。调用AppDomain.Unload方法的线程将继续运行;对AppDomain.Unload的调用时同步进行的。
在Ch22-1-AppDomain应用程序中,所有工作都有一个线程来做。因此,任何时候只要调用AppDomain.Unload,都不可能有另一个线程在要卸载的AppDomain中。因此,CLR不必抛出任何ThreadAbortException异常。
顺便说一句,当一个线程调用AppDomain.Unload方法时,针对要卸载的AppDomain中的线程,CLR会给他们10秒钟的时间离开。10秒钟之后,如果调用AppDomain.Unload方法的线程还没有返回,CLR将抛出一个CannotUnloadAppDomainException异常,AppDomain将来可能会、也可能不会卸载。
最新文章
- 推荐一篇关于java 学习的文章,感觉写的很不错
- [AlwaysOn Availability Groups]排查:AG超过RPO
- 修复 VirtualBox 下 Ubuntu 14.10 屏幕分辨率问题
- php get_magic_quotes_gpc()函数
- 夺命雷公狗ThinkPHP项目之----企业网站24之网站前台获取当前栏目和顶级栏目
- 能源项目xml文件标签释义--CommonsMultipartResolver
- Codeforces Round #111 (Div. 2)
- 慕课网-安卓工程师初养成-2-6 Java中的数据类型
- 转: android studio 消除SDK更新时的“https://dl-ssl.google.com refused”错误
- Jenkins配置Java项目1(Java+Maven+Tomcat)
- JavaScript学习笔记(十三)——生成器(generator)
- java 之 建造者模式(大话设计模式)
- 从开源项目看python代码注释
- C# 枚举特性 FlagAttribute 的应用
- boost::asio::spawn 将一统C++网络库
- DIV中文字换行显示
- linux在线安装JDK(1.8版本)
- 第一次Java测试及感触
- 做u盘启动重装系统 进winPE 出现 cdboot:couldn't find ntldr 解决办法
- C# - 企业框架下的存储过程输出参数