Partager via


Why isn't there an Assembly.Unload method?

We frequently get asked why you cannot unload an assembly from an app domain. After all, you can do a FreeLibrary() in unmanaged code to unload a DLL, and the CLR is just using DLL's right?

Reasons to Want to Unload

There are generally two reasons that you want to unload an assembly: space and versioning. The former is obvious, you want to free up allocated memory in the process. The second refers to wanting to load a newer version of an assembly, as for example Asp.Net does when you compile a new version of your application. If the assembly's underlying file is locked in the file system, you cannot replace it.

Why Not Support It?

There are a few problems with unloading an individual assembly, some of them hard design issues and some of them just work:

1. First off, you are running that code in the app domain (duh!). That means there are potentially call sites and call stacks with addresses in them that are expecting to keep working. Have you ever gotten an access violation where your EIP points to 0x???????? That is an example where someone freed up a DLL, the pages got unmapped by the memory system, and then you tried to branch to it. This typically happens in COM when you have a ref counting error and you make an interface method call. We cannot afford to be as lose with managed code. We must guarantee we know all of the code you are executing and that it is type safe and verifiable. That means explicit tracking of anything that could be using that code, including GC objects and COM interop wrappers. This tracking is handled today around an app domain boundary. Tracking it at the assembly level becomes quite expensive.

2. Say you did manage to track all handles and references to already running code by an assembly. Assuming you didn't ngen the code, once you successfully freed up the assembly, you have only freed up the metadata and IL. The JIT'd code is still allocated in the app domain loader heap (JIT'd methods are allocated sequentially in a buffer in the order in which they are called). Now we do know the identity of all methods, so we could go back and track down all of the code and turn the heap into a malloc style heap with a free list (in fact we had a code pitching jitter we prototyped way back when on Windows CE that did precisely this to limit the overall JIT heap size). So this one is solvable and just falls into the work column with a small hit on allocation and jitted method locality (probably not enough to measure).

3. The final issue relates to code which has been loaded shared, otherwise more formally know as "domain neutral" (check out /shared on the ngen tool). In this mode, the code for an assembly is generated to be executed from any app domain (nothing hard wired). This has some interesting trade offs: on the one hand you can execute the same code in any app domain so it loads faster in subsequent app domain instances (its already there). On the other hand, the code must therefore be tracked in all app domains it has ever been loaded into before it can be freed. With the current v1.0 and v1.1 product it is not even possible to unload domain neutral code because of these restrictions.

In the end you should be getting the flavor that this is not an impossible feature to implement, but is also non-trivial. In essence, we have already built in the design around the notion of an app domain and amortized it across all assemblies, hence the model. I will not rule out having such a feature in the future. But it is not planned for the Whidbey product at this time.

So What's the Alternative?

It is recommended that you design your application around the application domain boundary naturally, where unload is fully supported. For example, Asp.Net hosts applications in an app domain and unloads them when they are no longer needed or out of date. SQL Server Yukon does the same thing for SQL/CLR. In addition, you can use the Shadow Copy feature of Fusion to avoid the file in use locking error (also used by Asp.Net). The added advantage of this model is that you can write your host to monitor and abort app domains which engage in bad behavior (such as using too much memory or resources). This can be very helpful when you are hosting potentially un-trusted or potentially less robust code.

If there is interest, I have been considering posting a hosting sample which does app domain recycling policy as this does come up quite a bit...

Comments

  • Anonymous
    May 31, 2004
    The comment has been removed

  • Anonymous
    May 31, 2004
    Also, thanks a lot for explaining this. It helps a lot to know this won't be repaired anytime soon.

  • Anonymous
    May 31, 2004
    I agree this is one of the biggest flaws in .NET design. We also chose not to use .NET for a project because of this.

  • Anonymous
    May 31, 2004
    If you really want to take the overhead hit of being able to load/unload single assemblies at a time, just write a simple wrapper class which manages the assembly -- loading, getting a reference to the assembly, and unloading it. The wrapper class would be responsible for creating the AppDomain on the fly and destroying it when you wanted to 'unload' the assembly.

    This isn't hard stuff folks.

    Managing assemblies you want to unload in AppDomains actually makes things easier in some respects, depending on your application model.

  • Anonymous
    May 31, 2004
    The comment has been removed

  • Anonymous
    May 31, 2004
    The comment has been removed

  • Anonymous
    May 31, 2004
    I am writing a windows forms application that will house multiple MDI children applications each in their own assembly. These MDI children are loaded dynamically. I would like to be able to unload an assembly so that I can bring in a new version without having to take down the whole parent application. I have attempted to put the MDI child in a separate appdomain but this is not possible due to WinForms serialzation problems. An Assembly.Unload would be very helpful to me.

  • Anonymous
    May 31, 2004
    The comment has been removed

  • Anonymous
    May 31, 2004
    Jazon Zander skriver om, hvorfor der
    ikke findes en Assembly.Unload metode.
    Vi lavede nemlig en arkitektur...

  • Anonymous
    May 31, 2004
    The comment has been removed

  • Anonymous
    May 31, 2004
    I would love to see an application sample.

    thanks

  • Anonymous
    June 01, 2004
    Another "workaround" is Light Weight Codegen in Whidbey. Hopefully, in the future Light Weight Codegen will also support creating types, that would really be nice work around.

    Using AppDomains is not an option for perf critical stuff.

  • Anonymous
    June 01, 2004
    The comment has been removed

  • Anonymous
    June 01, 2004
    The comment has been removed

  • Anonymous
    June 02, 2004
    Iam sorry but I see why lack of Assembly.Unload() method,makes (UI)Plugins or "Server Plugins" very difficult or impossible to write using .NET ?

  • Anonymous
    June 02, 2004
    QUICK RETYPE
    Iam sorry but I DO NOT see why lack of Assembly.Unload() method,makes (UI)Plugins or "Server Plugins" very difficult or impossible to write using .NET ?

  • Anonymous
    June 02, 2004
    Very interested in the hosting sample and app domain recycling

  • Anonymous
    June 02, 2004
    Well Java manages to unload Java classes, code & meta data just fine (it occurs after the last reference to the class & classloader dissapears). All the problems you talk about are solved by using this fancy thing called a Garbage Collector which I hear is already included in .NET.

  • Anonymous
    June 03, 2004
    The comment has been removed

  • Anonymous
    June 03, 2004
    Please make Assembly.Unload work and please make it work that my add-ins don't crash whenever we change the Assembly or Framework version numbers.

  • Anonymous
    June 04, 2004
    It seems like a lot of the comments revolve around a scenario using "plugins". I've tried to go the AppDomain loading/unloading route to implement such plugins, but it was just too much of a hassle - I ended up with a "load plugins on startup" solution - which is kind of a hassle for a Web Application which needs to be live most of the day. Has anyone had any success creating/destroying AppDomains from within a Web Application?

    It would be nice, since this is such a popular scenario, if there was a reference example of how to add solid plugin support to an application (basically your AppDomain loading/recycling example).

  • Anonymous
    June 04, 2004
    I tried to use separate AppDomain to load a managed dll that actually compiles a code on-the-fly to in-memory assembly and runs it. I then unload my AppDomain but memory was not released - the in-memory assembly seems to be loaded into a default domain as well.

    I need to do a lot of communications with the in-memory assembly and I need to re-compile it thousands of times. But when I am done with it - I know for sure there are no references and handles - I just want it gone.

    Despite all the good reasons noted here - I too think that this feature is a valuable one and wish it was implemented.

    There are million other ways to crash .NET app, why be afraid of this one.

  • Anonymous
    June 04, 2004
    Fix it now. If MS can't fix it maybe http://www.go-mono.com can. I wouldn't mind running Mono instead of .NET if this makes my add-ins work.

  • Anonymous
    June 09, 2004
    This would be a really cool Rotor research topic.

  • Anonymous
    June 09, 2004
    Samples! Yes, yes, yes! I have a major project in the framework and I just ran into this wall. I cannot and do not want to recode on a different environment as .net has made so many improvements if there is a good work around/solution I'll use it. I am alread using a interface based modle and have been keeping them in a separate asembly as I am loading to classes of dynamic plug-ins that have to interop. One class scripts against the other with the framework providing the fundamental services.
    Thanks,
    Sigurthr

  • Anonymous
    June 14, 2004
    I am using a script system in c#. When the user changes and compiles his new "versioned" class, tadaaaa! "Compiler error. your file is in use!!!". This is due to the f lack os Assmble.Unload method.....

  • Anonymous
    July 05, 2004
    hi,

    is there any chance or aspiration, that the Assembly.Unload method will be implemented in the new .Net version (v2.0)???

    Thanks,
    musti

  • Anonymous
    July 07, 2004
    Assembly.Unload

  • Anonymous
    July 21, 2004
    is there anyone from microsoft, who can answer my question from 7/6/2004 4:16AM????

    ...or is it true that microsoft dont think about it (Assembly.Unload)???<br><br>I have tried to solve my problem with AppDomains, but it is realy not a good way...(and it doesn`t solve my problem at the end )

    musti

  • Anonymous
    July 28, 2004
    Hi Musti - sorry for the delay; I've been on vacation. We do not have plans to implement an Unload method in V2.0. We are basically code complete with the release and down to stress testing and fit and finish style fixes. Doing Unload would be a pretty pervasive feature to implement which would touch too much of the runtime for this release.

    I have some folks working on samples as we speak; stay tuned...

    Jason

  • Anonymous
    January 15, 2005
    The comment has been removed

  • Anonymous
    April 07, 2005
    Well we ended up writing a VS.Net plugin to add to our developer testing tools (something like NUnitPlugin,...

  • Anonymous
    March 10, 2006
    What is an Application Domain (AD)?
    An Application Domain is a CLR feature that provides a unit of isolation...

  • Anonymous
    July 29, 2006
    Introduction
    The last couple of days I've been playing around with some stuff around WCF (formerly known...

  • Anonymous
    March 21, 2007
    There's no way to unload an individual assembly without unloading all of the appdomains containing it.

  • Anonymous
    August 31, 2007
    微软装配车的大门似乎只为货物装载敞开大门,却将卸载工人拒之门外。车门的钥匙只有一把,若要获得还需要你费一些心思。我在学习Remoting的时候,就遇到一个扰人的问题,就是Remoting为远程对象仅提...

  • Anonymous
    August 31, 2007
    http://www.blogcn.com/user8/flier_lu/index.html?id=2164751

  • Anonymous
    September 05, 2007
    I&#39;ve come to a case, where, in my application, i need to load the assembly dynamically. Its not a

  • Anonymous
    November 05, 2007
    What is an Application Domain (AD)? An Application Domain is a CLR feature that provides a unit of isolation

  • Anonymous
    October 28, 2008
    Sometimes you need to load an assembly for use or inspection.&#160; The problem is that loading an assembly

  • Anonymous
    January 17, 2009
    PingBack from http://www.hilpers.com/1174529-reflection-assembly-entladen

  • Anonymous
    March 24, 2009
    Abhinaba’s blog What’s new in Windows Mobile 6.1 and 6.5 around memory Dynamic assembly unloading Again

  • Anonymous
    May 29, 2009
    PingBack from http://paidsurveyshub.info/story.php?title=jason-zander-s-weblog-why-isn-t-there-an-assembly-unload-method

  • Anonymous
    June 01, 2009
    PingBack from http://woodtvstand.info/story.php?id=15553

  • Anonymous
    June 07, 2009
    PingBack from http://greenteafatburner.info/story.php?id=1804

  • Anonymous
    June 09, 2009
    PingBack from http://hairgrowthproducts.info/story.php?id=4030

  • Anonymous
    June 13, 2009
    PingBack from http://homelightingconcept.info/story.php?id=3697