Skip to main content
gamedev.net
🔒 Locked

Unloading Assemblies in .NET framework

Started by ggs 7 replies 1.5k views
Original Post
ggs
ggs
I want to know who is responsible for not allowing individual assemblies to be unloaded once any references to thier content have been dropped. While researching info for implementing scripting under .NET, I''ve come to realize that utilizing the .NET framework for anything which isnt compile once, is overly painful and really not worth the effort. Loading it into another AppDomain just isnt feasible due to the preformance hit for AppDomaon <-> AppDomain communication and the memory hit have having the virtual address space filled with DLL images and the JITed code taking up even more space. This just gets worse with all the code generation utilities which emit custom code and dump it into the address space. All this comes down to one ''simple'' reason; the lack of the ability unloading a single assembly once all references to its contents are dropped. It doesnt need to be automatic and I believe assembly unloading should be explicit. Somthing like: "Assembly.Unload( ref Assembly assembly );", it can walk the entire heap & stack to vertify that the assembly is ready to unload, preform expensive operations, just as long as it allows for that operation. Personally, the ability to unload an individual assembly would represents a much bigger improvement in functionaility in the framework that anything bar generics in the upcoming next version of C#. Stuff in longhorn might be another story, but there isnt enough solid info yet to tell.
joanusdmentia
joanusdmentia
Haven''t check this out or anything, but does Assembly derive from IDisposed? If so I imagine calling Assembly.Dispose() would unload the assembly.

As for what would happen if you try and use something that was in the assembly being unloaded an exception of some sort would be thrown when you tried to use it.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The nly verdict is vengeance; a vendett o
ggs
ggs
quote:
Original post by Anonymous Poster
what would happen to code in your assembly that uses types defined in an unloaded assembly?


Reading is fundemental . If you are using types in a to-be-unloaded assembly, there is still references to its content, thus cant be unloaded yet!


@joanusdmentia
Currently the only way to unload an assembly is to unload the entire appdomain. And even then it isnt guarantied to be unloaded.
joanusdmentia
joanusdmentia
Just checked it ouy myself, that''s a bit of a surprise.

Why do you want to unload an assembly anyway?
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The nly verdict is vengeance; a vendett o
ggs
ggs
quote:
Original post by joanusdmentia
Why do you want to unload an assembly anyway?

Scripting systems.

You normally want the ability to unload a script at some point which doesnt involve stopping & restarting the entire application.

There are a few other reasons, but thats the easiest to explain.
Ardaxus
Ardaxus
I''ve been thinking about this over the last couple of days after having checked out the subject a little more deeply, and have been trying to work out what options are available in order to implement this effectively. Currently I see the following problems:
* Assemblies can''t be unloaded, even from an application domain, whilst instances of their types exist in memory
* Use of extra application domains carries a decent amount of overhead and simply loading the assembly into a separate application domain is probably going to create other problems anyway.

So how do we get around this? I''d like to discuss with you guys possible solutions to the problem, or workarounds which can create the effect of being able to dynamically load and unload our plugged-in code without sacrificing the advantage of being able to run our "scripts" as native compiled parallel code.

I wonder if it''s possible to create some sort of "type" duplication solution. So basically you''d load the assembly into a separate appdomain (so you can drop it as soon as you''re done) and interrogate it for classes you need. You''d then somehow use that as a base to dynamically create copies of that class definition. The copied type would be what is instantiated. Any instances of that class that are created would not be associated with the original assembly. You could then get rid of the assembly without having to unload current instances of classes originally based in that assembly. I guess that of course leaves a memory issue of what happens when the class is updated, loaded in and duplicated as before, thus causing new instances of the desired type to be of the new class type. As the old instances are gradually removed when they are no longer needed, eventually we''re left with an obsolete class definition that''s sitting there doing nothing. That of course doesn''t account for the problem of, what if we are intending to "upgrade" the codebase of current instances of the class.

There may be other creative ways of achieving the goal, and I''d be eager to hear what you guys might be able to come up with.


Snowman | Ardaxus | Nathan

Snowman | Ardaxus | Nathan
ggs
ggs
Part of the fundemental problem is the .NET framework (as of v1.*) has no concept of deleting a type, or destructively removing parts of a type which is exposed to the managed layer.

In the profiling API, there is the concept of being told when a assembly/module/class is unloaded, but no way to trigger such an event.
joanusdmentia
joanusdmentia
quote:
Original post by Ardaxus
I wonder if it''s possible to create some sort of "type" duplication solution. So basically you''d load the assembly into a separate appdomain (so you can drop it as soon as you''re done) and interrogate it for classes you need. You''d then somehow use that as a base to dynamically create copies of that class definition. The copied type would be what is instantiated. Any instances of that class that are created would not be associated with the original assembly. You could then get rid of the assembly without having to unload current instances of classes originally based in that assembly. I guess that of course leaves a memory issue of what happens when the class is updated, loaded in and duplicated as before, thus causing new instances of the desired type to be of the new class type. As the old instances are gradually removed when they are no longer needed, eventually we''re left with an obsolete class definition that''s sitting there doing nothing. That of course doesn''t account for the problem of, what if we are intending to "upgrade" the codebase of current instances of the class.

Even if this "type duplication" system was possibly (I won''t say that it isn''t without checking into it properly, but I have my doubts) you end up with exactly the same problem. After you destroy the AppDomain with the original copies of the types you still have the new copies in your applications original AppDomain and can''t unload them.

quote:
Original post by ggs
You normally want the ability to unload a script at some point which doesn''t involve stopping & restarting the entire application.

The purpose behind unloading a script is usually to disable the functionalliy of that script. Is this mainly what you''re after? If so, can you achieve the same result without unloading the assembly?
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The nly verdict is vengeance; a vendett o

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.