I have created a small windows service that runs plugins.
Each plugin is a dll that gets loaded into its own seperate AppDomain
using CreateInstanceAndUnwrap
method and I keep a reference to the AppDomain
.
Once the plugin completes, I shut down the AppDomain
that is created for that plugin. I'm using shadow copy to allow updates to the plugins while they are running in the framework.
It has run for 6 months perfectly untill last week when I decided to put the core functionality of the framework into a seperate dll also and execute that dll in a seperate AppDomain
.
The way it works right now is:
- Windows service comes up.
- The core dll is loaded and executed using
CreateInstanceAndUnwrap
which in turn is responsible for running the plugins in their own seperateAppDomain
I have couple of different locations for assemblies:
- Bin Folder (Bin of the windows service holds only dlls used by the service)
- Core DLLs Folder (Core dlls get dropped in here)
- References Folder (any references get dropped in here)
- Plugins Folder (plugins get dropped in here)
I resolve any unfound dlls by hooking up to each the OnAssemblyResolve
event on the AppDomain
. This allows dlls to be loaded from over the network.
Now the problem is the windows service ran for one day and the memory went as high as 1.5G. I created a dump of the memory and seems like loaded modules are only 100MB of the whole 1.5G so I dont know where all this memory is going to.
Using debugging I saw an alert for heap fragmentation but I have no idea where I should start to diagnose the issue. Usually when the framework runs for a day it consumed something like 100M.
Also this is not related to the plugins either; when I rolled back my changes to the framework the memroy usage became normal as before. When I create the AppDomain
for plugins, I switch the basePath and the bin path of the AppDomain
to CORE and References folders that have most of the dlls in there in hope that the assembly resolve gets called less often.
I looked at fusion logs and also read a little bit more about load contexts like default, from, and none but im not sure if thats the right path to take.
Any ideas?