AppDomain 卸载后程序集未卸载? [英] Assemblies not unloading after AppDomain unload?

查看:27
本文介绍了AppDomain 卸载后程序集未卸载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 AppDomain 来加载程序集,然后卸载它们.

I'm using an AppDomain in order to load assemblies and then unload them.

但是,我遇到了一个非常奇怪的问题.卸载 AppDomain 后 - 我仍然可以在进程资源管理器中看到某些程序集被多次加载!为什么有加载的程序集的剩余部分?AppDomain.Unload 不会释放所有 AppDomain 加载的内存吗?

However, I'm having a very strage problem. After the AppDomain is unloaded - I can still see in process explorer that some assemblies are loaded multiple times! Why are there remainders of the loaded assemblies? Doesn't an AppDomain.Unload frees all the AppDomain's loaded memory?

您可以在附图中看到:

AppDomain 总数为 3(我在进程的生命周期中创建了 3 个 AppDomain)

Total AppDomains are 3 (I created 3 AppDomains in the process's life-cycle)

AppDomains: 1(目前仅存在 1 个 AppDomain)

AppDomains: 1 (Currently only 1 AppDomain exists)

出于某种原因,正如您在下面加载的 DLL 部分中看到的那样 - 程序集被多次加载到进程中..

And for some reason, as you can see in the loaded DLL section bellow - Assemblies are loaded multiple times into the process..

代码:

AppDomain fetcherDomain = AppDomain.CreateDomain("StatusFetcher");
try
{
    var fetcher = (LocalStatusFetcher)fetcherDomain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().CodeBase, typeof(LocalStatusFetcher).FullName);
    //doing some other stuff that is not interesting...
}
finally
{
    AppDomain.Unload(fetcherDomain);
}

是的,LocalStatusFetcher 确实继承了 MarshalByRefObject...

And yes, LocalStatusFetcher does inherit MarshalByRefObject...

推荐答案

您正在加载到外部应用程序域中的程序集很有可能被混入当前应用程序域.发生这种情况的方式有 很多,但您的问题尤其是将 Assembly.GetExecutingAssembly().CodeBase 传递给 CreateInstanceFromAndUnwrap 方法.调用 Assembly.GetExecutingAssembly() 将当前执行的程序集加载到 current 应用程序域中,并将 .CodeBase 属性传递给CreateInstanceFromAndUnwrap 将尝试在实例化目标代理之前将目标程序集(位于应用程序路径或 GAC 中)加载到目标域中.目前,除了可能的出血问题之外,我认为这段代码没有任何问题.

There's a very high possibility that the assemblies you're loading into the foreign application domain are being bled into the current one. There are tons of ways that this can happen, but your problem in particular is passing Assembly.GetExecutingAssembly().CodeBase to the CreateInstanceFromAndUnwrap method. A call to Assembly.GetExecutingAssembly() loads the currently executing assembly into the current app domain, and passing the .CodeBase property to CreateInstanceFromAndUnwrap will attempt to load the target assembly (located in the application path or in the GAC) into the target domain before instantiating your target proxy. Currently, I see nothing wrong with this code other than the possible bleeding issue.

如果您有多个应用程序域,那么您将在 LoadFrom 上下文中看到程序集的多个副本,因为在 AppDomains 之间共享的唯一程序集是 mscorlib.dll.除非我误解了你的问题,否则我认为你看到的是正常的.

If you have multiple application domains then you'll see multiple copies of the assembly in the LoadFrom context because the only assembly that is shared across AppDomains is mscorlib.dll. Unless I'm misunderstanding your question I think what you're seeing is normal.

这篇关于AppDomain 卸载后程序集未卸载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆