Unloading AppDomain [modified]
-
Newbi to the whole appdomain-ting but my understanding was that it is a controllable area of a process where I can load code where I can enforce security and at any time unload it. I want to use it to extend my applications functionallity and at any time given a specific term can unload from memory and eventually restart. This way I could have memory intense parts loaded when I need them instead of all the time. However I don't get this to work but I'm probably doing some beginners error?1 My code goes something like this:
AppDomainClient - Plugin.vb (class implementing AppDomainInterfaces.IPlugin) AppDomainInterfaces - IPlugin.vb - IPluginFactory (Inherits MarshalByRefObject) AppDomainApplication - MainForm.vb
I start the MainForm by creating an AppDomain. The appdomain object is passed to an instace of the IPluginFactory and used to CreateInstanceAndUnwrap an instance of the Plugin class. The Plugin class is returned as the IPlugin interface to the MainForm. In the constructor of the Plugin class a method EatMemory is called which allocates a very big string. This workes fine and the memory allocated by the application goes through the roof! When I try to unload the AppDomain I don't get any errors but the memory is still occupied with the same number of bytes as before I ran the unload command:AppDomain.Unload("MyCustomAppDomain")
I was expecting it to decrease mack to what I had before I loaded the Plugin? -- modified at 7:37 Monday 3rd July, 2006 -
Newbi to the whole appdomain-ting but my understanding was that it is a controllable area of a process where I can load code where I can enforce security and at any time unload it. I want to use it to extend my applications functionallity and at any time given a specific term can unload from memory and eventually restart. This way I could have memory intense parts loaded when I need them instead of all the time. However I don't get this to work but I'm probably doing some beginners error?1 My code goes something like this:
AppDomainClient - Plugin.vb (class implementing AppDomainInterfaces.IPlugin) AppDomainInterfaces - IPlugin.vb - IPluginFactory (Inherits MarshalByRefObject) AppDomainApplication - MainForm.vb
I start the MainForm by creating an AppDomain. The appdomain object is passed to an instace of the IPluginFactory and used to CreateInstanceAndUnwrap an instance of the Plugin class. The Plugin class is returned as the IPlugin interface to the MainForm. In the constructor of the Plugin class a method EatMemory is called which allocates a very big string. This workes fine and the memory allocated by the application goes through the roof! When I try to unload the AppDomain I don't get any errors but the memory is still occupied with the same number of bytes as before I ran the unload command:AppDomain.Unload("MyCustomAppDomain")
I was expecting it to decrease mack to what I had before I loaded the Plugin? -- modified at 7:37 Monday 3rd July, 2006matsnas wrote:
When I try to unload the AppDomain I don't get any errors but the memory is still occupied with the same number of bytes as before I ran the unload command:
Did you determine this using the TaskManager or using the Performance Monitor or a Memory Profiler? If you used TaskManager, you picked possibly the worst tool you could use for checking the memory use of your app. TaskManager will show you the memory use of the entire virtual machine your app is running in (the .NET Common Language Runtime). This includes memory that the CLR has reserved for your app, but not in actual use by your application... Dave Kreskowiak Microsoft MVP - Visual Basic -- modified at 13:42 Monday 3rd July, 2006
-
matsnas wrote:
When I try to unload the AppDomain I don't get any errors but the memory is still occupied with the same number of bytes as before I ran the unload command:
Did you determine this using the TaskManager or using the Performance Monitor or a Memory Profiler? If you used TaskManager, you picked possibly the worst tool you could use for checking the memory use of your app. TaskManager will show you the memory use of the entire virtual machine your app is running in (the .NET Common Language Runtime). This includes memory that the CLR has reserved for your app, but not in actual use by your application... Dave Kreskowiak Microsoft MVP - Visual Basic -- modified at 13:42 Monday 3rd July, 2006
Well actually I did but only because I didn't get the Performance Monitor working in a good way. Anyway I also tried to have my plugin display a WinForm in it constructor believing that it would go away when my plugin's appdomain was unloaded but it didn't. I'm missing some vital part of understanding here I think. All documentation refer to the current AppDomain beeing "unloaded" but what do they actually mean by unloaded? Valid for unloading when the GC feels like it? I would have guessed that the AppDomain stopped/killed and all allocated memory space freed.
-
Well actually I did but only because I didn't get the Performance Monitor working in a good way. Anyway I also tried to have my plugin display a WinForm in it constructor believing that it would go away when my plugin's appdomain was unloaded but it didn't. I'm missing some vital part of understanding here I think. All documentation refer to the current AppDomain beeing "unloaded" but what do they actually mean by unloaded? Valid for unloading when the GC feels like it? I would have guessed that the AppDomain stopped/killed and all allocated memory space freed.
Just because you unloaded an AppDomian, doesn't mean that all the data in it just "went away". Assemblies used by multiple domains in a process can be shared. This means that the assembly is domain-neutral. Data in domain-neutral assemblies in not freed until the entire app shuts down, not just the AppDomain it was allocated in. You might want to take a look at a couple examples of AppDomain PlugIns. http://www.devsource.com/article2/0,1759,1790388,00.asp[^] http://www.google.com/search?hl=en&q=appdomain+plugins[^] http://msdn.microsoft.com/msdnmag/issues/03/10/Plug-Ins/default.aspx[^] Dave Kreskowiak Microsoft MVP - Visual Basic
-
Just because you unloaded an AppDomian, doesn't mean that all the data in it just "went away". Assemblies used by multiple domains in a process can be shared. This means that the assembly is domain-neutral. Data in domain-neutral assemblies in not freed until the entire app shuts down, not just the AppDomain it was allocated in. You might want to take a look at a couple examples of AppDomain PlugIns. http://www.devsource.com/article2/0,1759,1790388,00.asp[^] http://www.google.com/search?hl=en&q=appdomain+plugins[^] http://msdn.microsoft.com/msdnmag/issues/03/10/Plug-Ins/default.aspx[^] Dave Kreskowiak Microsoft MVP - Visual Basic
Thanks, I'll have a go at the examples you posted. Just one question though, I was expecting to be able to have other programmers write plugins for my application but using AppDomains I would be able to securly shut these plugins down and unload them without disturbing the plugin host? Note! Written from memory so there might be compilation errors...
namespace AppDomainHost public class Host private mAppDomain as AppDomain private mIPlugin as AppDomainInterfaces.IPlugin public sub New() Dim vEvidence As Evidence = AppDomain.CurrentDomain.Evidence mAppDomain = AppDomain.CreateDomain("MyAppDomain", vEvidence) mIPlugin = AppDomainInterfaces.Factory.CreateIPlugin(mAppDomain, "AppDomainClient", "AppDomainClient.Client") mIPlugin.Connect AppDomain.Unload(mAppDomain) end sub end class end namespace namespace AppDomainClient <serializable()> _ public class Client implements AppDomainInterfaces.IPlugin private mForm as Form public sub New() mForm = new Form() end sub public sub Connect() implements AppDomainInterfaces.IPlugin.Connect msgbox("Connected") end sub end class end namespace namespace AppDomainInterfaces public interface IPlugin sub Connect() end interface public class Factory function CreateIPlugin(byval pAppDomain as AppDomain, byval pAssembly as string, byval pType as string) dim vIPlugin = directcast(pAppDomain.CreateInstanceAndUnwrap(pAssembly, pType), IPlugin) return vIPlugin end function end class end namespace
-
Just because you unloaded an AppDomian, doesn't mean that all the data in it just "went away". Assemblies used by multiple domains in a process can be shared. This means that the assembly is domain-neutral. Data in domain-neutral assemblies in not freed until the entire app shuts down, not just the AppDomain it was allocated in. You might want to take a look at a couple examples of AppDomain PlugIns. http://www.devsource.com/article2/0,1759,1790388,00.asp[^] http://www.google.com/search?hl=en&q=appdomain+plugins[^] http://msdn.microsoft.com/msdnmag/issues/03/10/Plug-Ins/default.aspx[^] Dave Kreskowiak Microsoft MVP - Visual Basic
Ok, I'm not sure I understand what happens or what to do about it but as the first article talks about leaking datum into the original AppDomain it seems like loading the Plugin loads an extra assemby into AppDomain.CurrentDomain. I thougt that I was only calling a sub on the interface object IPlugin. Why is the AppDomainClient.DLL loaded and how do I prevent this? More correctly, how do I assure that my plugin can be removed from memory at any time?
-
Thanks, I'll have a go at the examples you posted. Just one question though, I was expecting to be able to have other programmers write plugins for my application but using AppDomains I would be able to securly shut these plugins down and unload them without disturbing the plugin host? Note! Written from memory so there might be compilation errors...
namespace AppDomainHost public class Host private mAppDomain as AppDomain private mIPlugin as AppDomainInterfaces.IPlugin public sub New() Dim vEvidence As Evidence = AppDomain.CurrentDomain.Evidence mAppDomain = AppDomain.CreateDomain("MyAppDomain", vEvidence) mIPlugin = AppDomainInterfaces.Factory.CreateIPlugin(mAppDomain, "AppDomainClient", "AppDomainClient.Client") mIPlugin.Connect AppDomain.Unload(mAppDomain) end sub end class end namespace namespace AppDomainClient <serializable()> _ public class Client implements AppDomainInterfaces.IPlugin private mForm as Form public sub New() mForm = new Form() end sub public sub Connect() implements AppDomainInterfaces.IPlugin.Connect msgbox("Connected") end sub end class end namespace namespace AppDomainInterfaces public interface IPlugin sub Connect() end interface public class Factory function CreateIPlugin(byval pAppDomain as AppDomain, byval pAssembly as string, byval pType as string) dim vIPlugin = directcast(pAppDomain.CreateInstanceAndUnwrap(pAssembly, pType), IPlugin) return vIPlugin end function end class end namespace
I really couldn't tell you. I've done plugin's before, but not in AppDomains. I've never needed the ability to unload plugin's. Dave Kreskowiak Microsoft MVP - Visual Basic